From ce105e87404c53c09b8f9af4f76736b50458f0c7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 5 Nov 2014 18:26:01 +0100 Subject: (error) va_list 'args' was opened but not closed by va_end() The manpage of va_start and co additionally says: On some systems, va_end contains a closing '}' matching a '{' in va_start, so that both macros must occur in the same function, and in a way that allows this. So instead of return/breaking instantly, we save the return, make a proper turndown with va_end in all cases and only end after that. Reported-By: cppcheck Git-Dch: Ignore --- apt-pkg/contrib/strutl.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index ebf9c9ea6..0ac587a9e 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1319,10 +1319,12 @@ void ioprintf(ostream &out,const char *format,...) va_list args; ssize_t size = 400; while (true) { + bool ret = false; va_start(args,format); - if (iovprintf(out, format, args, size) == true) - return; + ret = iovprintf(out, format, args, size); va_end(args); + if (ret == true) + return; } } void strprintf(string &out,const char *format,...) @@ -1331,10 +1333,12 @@ void strprintf(string &out,const char *format,...) ssize_t size = 400; std::ostringstream outstr; while (true) { + bool ret = false; va_start(args,format); - if (iovprintf(outstr, format, args, size) == true) - break; + ret = iovprintf(outstr, format, args, size); va_end(args); + if (ret == true) + break; } out = outstr.str(); } -- cgit v1.2.3 From 586d8704716a10e0f8b9c400cab500f5353eebe6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 26 Oct 2014 23:17:03 +0100 Subject: replace ignore-deprecated #pragma dance with _Pragma For compatibility we use/provide and fill quiet some deprecated methods and fields, which subsequently earns us a warning for using them. These warnings therefore have to be disabled for these codeparts and that is what this change does now in a slightly more elegant way. Git-Dch: Ignore --- apt-pkg/contrib/hashes.cc | 27 ++++++--------------------- apt-pkg/contrib/hashes.h | 9 ++------- apt-pkg/contrib/macros.h | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 28 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 55180c642..6e7080bc9 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -258,10 +258,7 @@ public: bool Hashes::Add(const unsigned char * const Data,unsigned long long const Size, unsigned int const Hashes) { bool Res = true; -#if __GNUC__ >= 4 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif +APT_IGNORE_DEPRECATED_PUSH if ((Hashes & MD5SUM) == MD5SUM) Res &= MD5.Add(Data, Size); if ((Hashes & SHA1SUM) == SHA1SUM) @@ -270,9 +267,7 @@ bool Hashes::Add(const unsigned char * const Data,unsigned long long const Size, Res &= SHA256.Add(Data, Size); if ((Hashes & SHA512SUM) == SHA512SUM) Res &= SHA512.Add(Data, Size); -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif +APT_IGNORE_DEPRECATED_POP d->FileSize += Size; return Res; } @@ -323,28 +318,18 @@ bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes HashStringList Hashes::GetHashStringList() { HashStringList hashes; -#if __GNUC__ >= 4 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif +APT_IGNORE_DEPRECATED_PUSH hashes.push_back(HashString("MD5Sum", MD5.Result().Value())); hashes.push_back(HashString("SHA1", SHA1.Result().Value())); hashes.push_back(HashString("SHA256", SHA256.Result().Value())); hashes.push_back(HashString("SHA512", SHA512.Result().Value())); -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif +APT_IGNORE_DEPRECATED_POP std::string SizeStr; strprintf(SizeStr, "%llu", d->FileSize); hashes.push_back(HashString("Checksum-FileSize", SizeStr)); return hashes; } -#if __GNUC__ >= 4 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif +APT_IGNORE_DEPRECATED_PUSH Hashes::Hashes() { d = new PrivateHashes(); } Hashes::~Hashes() { delete d; } -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif +APT_IGNORE_DEPRECATED_POP diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index e2e213855..ca186d704 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -189,15 +189,10 @@ class Hashes HashStringList GetHashStringList(); -#if __GNUC__ >= 4 - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif +APT_IGNORE_DEPRECATED_PUSH Hashes(); virtual ~Hashes(); -#if __GNUC__ >= 4 - #pragma GCC diagnostic pop -#endif +APT_IGNORE_DEPRECATED_POP private: APT_HIDDEN APT_CONST inline unsigned int boolsToFlag(bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512) diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index 3a5e37c63..c0af4b2c8 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -132,6 +132,22 @@ #endif #endif +#if __GNUC__ >= 4 + #define APT_IGNORE_DEPRECATED_PUSH \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + #define APT_IGNORE_DEPRECATED_POP \ + _Pragma("GCC diagnostic pop") + #define APT_IGNORE_DEPRECATED(XXX) \ + APT_IGNORE_DEPRECATED_PUSH \ + XXX \ + APT_IGNORE_DEPRECATED_POP +#else + #define APT_IGNORE_DEPRECATED_PUSH + #define APT_IGNORE_DEPRECATED_POP + #define APT_IGNORE_DEPRECATED(XXX) XXX +#endif + // These lines are extracted by the makefiles and the buildsystem // Increasing MAJOR or MINOR results in the need of recompiling all // reverse-dependencies of libapt-pkg against the new SONAME. -- cgit v1.2.3 From ccf6bdb3efc54165c76b42aae94c498a36acbe1b Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 14:20:36 +0100 Subject: use a abi version check similar to the gcc check Git-Dch: Ignore --- apt-pkg/contrib/macros.h | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index c0af4b2c8..14541d4d8 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -156,5 +156,6 @@ #define APT_PKG_MAJOR 4 #define APT_PKG_MINOR 15 #define APT_PKG_RELEASE 0 +#define APT_PKG_ABI ((APT_PKG_MAJOR * 100) + APT_PKG_MINOR) #endif -- cgit v1.2.3 From 02e20767719873fa8f1919bd0e7a75f63e00c484 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 17:49:36 +0100 Subject: guard const-ification API changes Git-Dch: Ignore --- apt-pkg/contrib/hashes.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index ca186d704..154862457 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -55,6 +55,8 @@ class HashString // get hash type used std::string HashType() const { return Type; }; std::string HashValue() const { return Hash; }; + APT_DEPRECATED std::string HashType() { return Type; }; + APT_DEPRECATED std::string HashValue() { return Hash; }; // verify the given filename against the currently loaded hash bool VerifyFile(std::string filename) const; -- cgit v1.2.3 From fa5404ab01bdf06eaf147d9f133139e6c89b906a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 7 Nov 2014 18:18:14 +0100 Subject: explicit overload methods instead of adding parameters Adding a new parameter (with a default) is an ABI break, but you can overload a method, which is "just" an API break for everyone doing references to this method (aka: nobody). Git-Dch: Ignore --- apt-pkg/contrib/configuration.cc | 6 ++++++ apt-pkg/contrib/configuration.h | 8 ++++++++ 2 files changed, 14 insertions(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 4380d64b9..483d5bb1b 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -253,6 +253,12 @@ string Configuration::FindDir(const char *Name,const char *Default) const // Configuration::FindVector - Find a vector of values /*{{{*/ // --------------------------------------------------------------------- /* Returns a vector of config values under the given item */ +#if APT_PKG_ABI < 413 +vector Configuration::FindVector(const char *Name) const +{ + return FindVector(Name, ""); +} +#endif vector Configuration::FindVector(const char *Name, std::string const &Default) const { vector Vec; diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 2ecea8bee..8d7d51037 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -84,8 +84,16 @@ class Configuration * * \param Name of the parent node * \param Default list of values separated by commas */ +#if APT_PKG_ABI >= 413 std::vector FindVector(const char *Name, std::string const &Default = "") const; std::vector FindVector(std::string const &Name, std::string const &Default = "") const { return FindVector(Name.c_str(), Default); }; +#else + std::vector FindVector(const char *Name, std::string const &Default) const; + std::vector FindVector(std::string const &Name, std::string const &Default) const { return FindVector(Name.c_str(), Default); }; + std::vector FindVector(const char *Name) const; + std::vector FindVector(std::string const &Name) const { return FindVector(Name.c_str(), ""); }; +#endif + int FindI(const char *Name,int const &Default = 0) const; int FindI(std::string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);}; bool FindB(const char *Name,bool const &Default = false) const; -- cgit v1.2.3 From ad7e0941b376d792911f240377094a2e78ca8756 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 8 Nov 2014 18:14:46 +0100 Subject: streamline display of --help in all tools By convention, if I run a tool with --help or --version I expect it to exit successfully with the usage, while if I do call it wrong (like without any parameters) I expect the usage message shown with a non-zero exit. --- apt-pkg/contrib/cmndline.cc | 3 +++ apt-pkg/contrib/cmndline.h | 1 + 2 files changed, 4 insertions(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 93c1f4664..ff8b09ebc 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -33,6 +33,9 @@ using namespace std; CommandLine::CommandLine(Args *AList,Configuration *Conf) : ArgList(AList), Conf(Conf), FileList(0) { +} +CommandLine::CommandLine() : ArgList(NULL), Conf(NULL), FileList(0) +{ } /*}}}*/ // CommandLine::~CommandLine - Destructor /*{{{*/ diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h index 143df58b2..58cbaa8c3 100644 --- a/apt-pkg/contrib/cmndline.h +++ b/apt-pkg/contrib/cmndline.h @@ -91,6 +91,7 @@ class CommandLine static CommandLine::Args MakeArgs(char ShortOpt, char const *LongOpt, char const *ConfName, unsigned long Flags) APT_CONST; + CommandLine(); CommandLine(Args *AList,Configuration *Conf); ~CommandLine(); }; -- cgit v1.2.3 From 3f439e2b7126fb82952cd7bc12b8d6cb01352219 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 18 Aug 2013 23:17:05 +0200 Subject: add a simple container for HashStrings APT supports more than just one HashString and even allows to enforce the usage of a specific hash. This class is intended to help with storage and passing around of the HashStrings. The cherry-pick here the un-const-ification of HashType() compared to f4c3850ea335545e297504941dc8c7a8f1c83358. The point of this commit is adding infrastructure for the next one. All by itself, it just adds new symbols. Git-Dch: Ignore --- apt-pkg/contrib/hashes.cc | 118 ++++++++++++++++++++++++++++++++++++++++------ apt-pkg/contrib/hashes.h | 84 ++++++++++++++++++++++++++++++++- 2 files changed, 187 insertions(+), 15 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 15f83615d..bb11a3fca 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -27,7 +27,7 @@ #include /*}}}*/ -const char* HashString::_SupportedHashes[] = +const char * HashString::_SupportedHashes[] = { "SHA512", "SHA256", "SHA1", "MD5Sum", NULL }; @@ -42,11 +42,16 @@ HashString::HashString(std::string Type, std::string Hash) : Type(Type), Hash(Ha HashString::HashString(std::string StringedHash) /*{{{*/ { - // legacy: md5sum without "MD5Sum:" prefix - if (StringedHash.find(":") == std::string::npos && StringedHash.size() == 32) + if (StringedHash.find(":") == std::string::npos) { - Type = "MD5Sum"; - Hash = StringedHash; + // legacy: md5sum without "MD5Sum:" prefix + if (StringedHash.size() == 32) + { + Type = "MD5Sum"; + Hash = StringedHash; + } + if(_config->FindB("Debug::Hashes",false) == true) + std::clog << "HashString(string): invalid StringedHash " << StringedHash << std::endl; return; } std::string::size_type pos = StringedHash.find(":"); @@ -82,25 +87,25 @@ std::string HashString::GetHashForFile(std::string filename) const /*{{{*/ std::string fileHash; FileFd Fd(filename, FileFd::ReadOnly); - if(Type == "MD5Sum") + if(strcasecmp(Type.c_str(), "MD5Sum") == 0) { MD5Summation MD5; MD5.AddFD(Fd); fileHash = (std::string)MD5.Result(); } - else if (Type == "SHA1") + else if (strcasecmp(Type.c_str(), "SHA1") == 0) { SHA1Summation SHA1; SHA1.AddFD(Fd); fileHash = (std::string)SHA1.Result(); } - else if (Type == "SHA256") + else if (strcasecmp(Type.c_str(), "SHA256") == 0) { SHA256Summation SHA256; SHA256.AddFD(Fd); fileHash = (std::string)SHA256.Result(); } - else if (Type == "SHA512") + else if (strcasecmp(Type.c_str(), "SHA512") == 0) { SHA512Summation SHA512; SHA512.AddFD(Fd); @@ -111,20 +116,105 @@ std::string HashString::GetHashForFile(std::string filename) const /*{{{*/ return fileHash; } /*}}}*/ -const char** HashString::SupportedHashes() +const char** HashString::SupportedHashes() /*{{{*/ { return _SupportedHashes; } - -APT_PURE bool HashString::empty() const + /*}}}*/ +APT_PURE bool HashString::empty() const /*{{{*/ { return (Type.empty() || Hash.empty()); } + /*}}}*/ +std::string HashString::toStr() const /*{{{*/ +{ + return Type + ":" + Hash; +} + /*}}}*/ +APT_PURE bool HashString::operator==(HashString const &other) const /*{{{*/ +{ + return (strcasecmp(Type.c_str(), other.Type.c_str()) == 0 && Hash == other.Hash); +} +APT_PURE bool HashString::operator!=(HashString const &other) const +{ + return !(*this == other); +} + /*}}}*/ + +HashString const * HashStringList::find(char const * const type) const /*{{{*/ +{ + if (type == NULL || type[0] == '\0') + { + std::string forcedType = _config->Find("Acquire::ForceHash", ""); + if (forcedType.empty() == false) + return find(forcedType.c_str()); + for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) + for (std::vector::const_iterator hs = list.begin(); hs != list.end(); ++hs) + if (strcasecmp(hs->HashType().c_str(), *t) == 0) + return &*hs; + return NULL; + } + for (std::vector::const_iterator hs = list.begin(); hs != list.end(); ++hs) + if (strcasecmp(hs->HashType().c_str(), type) == 0) + return &*hs; + return NULL; +} + /*}}}*/ +bool HashStringList::supported(char const * const type) /*{{{*/ +{ + for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) + if (strcasecmp(*t, type) == 0) + return true; + return false; +} + /*}}}*/ +bool HashStringList::push_back(const HashString &hashString) /*{{{*/ +{ + if (hashString.HashType().empty() == true || + hashString.HashValue().empty() == true || + supported(hashString.HashType().c_str()) == false) + return false; + + // ensure that each type is added only once + HashString const * const hs = find(hashString.HashType().c_str()); + if (hs != NULL) + return *hs == hashString; -std::string HashString::toStr() const + list.push_back(hashString); + return true; +} + /*}}}*/ +bool HashStringList::VerifyFile(std::string filename) const /*{{{*/ { - return Type + std::string(":") + Hash; + if (list.empty() == true) + return false; + HashString const * const hs = find(NULL); + if (hs == NULL || hs->VerifyFile(filename) == false) + return false; + return true; } + /*}}}*/ +bool HashStringList::operator==(HashStringList const &other) const /*{{{*/ +{ + short matches = 0; + for (const_iterator hs = begin(); hs != end(); ++hs) + { + HashString const * const ohs = other.find(hs->HashType()); + if (ohs == NULL) + continue; + if (*hs != *ohs) + return false; + ++matches; + } + if (matches == 0) + return false; + return true; +} +bool HashStringList::operator!=(HashStringList const &other) const +{ + return !(*this == other); +} + /*}}}*/ // Hashes::AddFD - Add the contents of the FD /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 7a62f8a8f..5a4213868 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,7 @@ class HashString protected: std::string Type; std::string Hash; - static const char* _SupportedHashes[10]; + static const char * _SupportedHashes[10]; // internal helper std::string GetHashForFile(std::string filename) const; @@ -53,6 +54,8 @@ class HashString // get hash type used std::string HashType() { return Type; }; + std::string HashType() const { return Type; }; + std::string HashValue() const { return Hash; }; // verify the given filename against the currently loaded hash bool VerifyFile(std::string filename) const; @@ -64,11 +67,90 @@ class HashString // helper std::string toStr() const; // convert to str as "type:hash" bool empty() const; + bool operator==(HashString const &other) const; + bool operator!=(HashString const &other) const; // return the list of hashes we support static APT_CONST const char** SupportedHashes(); }; +class HashStringList +{ + public: + /** find best hash if no specific one is requested + * + * @param type of the checksum to return, can be \b NULL + * @return If type is \b NULL (or the empty string) it will + * return the 'best' hash; otherwise the hash which was + * specifically requested. If no hash is found \b NULL will be returned. + */ + HashString const * find(char const * const type) const; + HashString const * find(std::string const &type) const { return find(type.c_str()); } + /** check if the given hash type is supported + * + * @param type to check + * @return true if supported, otherwise false + */ + static APT_PURE bool supported(char const * const type); + /** add the given #HashString to the list + * + * @param hashString to add + * @return true if the hash is added because it is supported and + * not already a different hash of the same type included, otherwise false + */ + bool push_back(const HashString &hashString); + /** @return size of the list of HashStrings */ + size_t size() const { return list.size(); } + + /** take the 'best' hash and verify file with it + * + * @param filename to verify + * @return true if the file matches the hashsum, otherwise false + */ + bool VerifyFile(std::string filename) const; + + /** is the list empty ? + * + * @return \b true if the list is empty, otherwise \b false + */ + bool empty() const { return list.empty(); } + + typedef std::vector::const_iterator const_iterator; + + /** iterator to the first element */ + const_iterator begin() const { return list.begin(); } + + /** iterator to the end element */ + const_iterator end() const { return list.end(); } + + /** start fresh with a clear list */ + void clear() { list.clear(); } + + /** compare two HashStringList for similarity. + * + * Two lists are similar if at least one hashtype is in both lists + * and the hashsum matches. All hashes are checked, if one doesn't + * match false is returned regardless of how many matched before. + */ + bool operator==(HashStringList const &other) const; + bool operator!=(HashStringList const &other) const; + + HashStringList() {} + + // simplifying API-compatibility constructors + HashStringList(std::string const &hash) { + if (hash.empty() == false) + list.push_back(HashString(hash)); + } + HashStringList(char const * const hash) { + if (hash != NULL && hash[0] != '\0') + list.push_back(HashString(hash)); + } + + private: + std::vector list; +}; + class Hashes { public: -- cgit v1.2.3 From c505fa33a6441b451971ce6c636cf2ca4dacdc1d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 28 Sep 2014 01:25:21 +0200 Subject: allow options between command and -- on commandline This used to work before we implemented a stricter commandline parser and e.g. the dd-schroot-cmd command constructs commandlines like this. Reported-By: Helmut Grohne --- apt-pkg/contrib/cmndline.cc | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 3799c822d..93c1f4664 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -47,23 +47,26 @@ CommandLine::~CommandLine() char const * CommandLine::GetCommand(Dispatch const * const Map, unsigned int const argc, char const * const * const argv) { - // if there is a -- on the line there must be the word we search for around it - // as -- marks the end of the options, just not sure if the command can be - // considered an option or not, so accept both + // if there is a -- on the line there must be the word we search for either + // before it (as -- marks the end of the options) or right after it (as we can't + // decide if the command is actually an option, given that in theory, you could + // have parameters named like commands) for (size_t i = 1; i < argc; ++i) { if (strcmp(argv[i], "--") != 0) continue; - ++i; - if (i < argc) + // check if command is before -- + for (size_t k = 1; k < i; ++k) for (size_t j = 0; Map[j].Match != NULL; ++j) - if (strcmp(argv[i], Map[j].Match) == 0) + if (strcmp(argv[k], Map[j].Match) == 0) return Map[j].Match; - i -= 2; - if (i != 0) + // see if the next token after -- is the command + ++i; + if (i < argc) for (size_t j = 0; Map[j].Match != NULL; ++j) if (strcmp(argv[i], Map[j].Match) == 0) return Map[j].Match; + // we found a --, but not a command return NULL; } // no --, so search for the first word matching a command -- cgit v1.2.3 From 2b4cead3c8eb3afb5aa5390b88c511477a7628d8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 9 Mar 2015 15:54:39 +0100 Subject: fix some new compiler warnings reported by gcc-5 Git-Dch: Ignore --- apt-pkg/contrib/configuration.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 483d5bb1b..42e35d32a 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -629,19 +629,19 @@ string Configuration::Item::FullTag(const Item *Stop) const tag/value. AsSectional enables Sectional parsing.*/ bool ReadConfigFile(Configuration &Conf,const string &FName,bool const &AsSectional, unsigned const &Depth) -{ +{ // Open the stream for reading - ifstream F(FName.c_str(),ios::in); - if (!F != 0) + ifstream F(FName.c_str(),ios::in); + if (F.fail() == true) return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str()); string LineBuffer; string Stack[100]; unsigned int StackPos = 0; - + // Parser state string ParentTag; - + int CurLine = 0; bool InComment = false; while (F.eof() == false) -- cgit v1.2.3 From 7e9b7ea8236a79580c4ca47712558096d66bad53 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 7 Apr 2015 18:31:12 +0200 Subject: demote VectorizeString gcc attribute from const to pure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g++-5 generates a slightly broken libapt which doesn't split architecture configurations correctly resulting in e.g. Packages files requested for the bogus architecture 'amd64,i386' instead of for amd64 and i386. The reason is an incorrectly applied attribute marking the function as const, while functions with pointer arguments are not allowed to be declared as such (note that char& is a char* in disguise). Demoting the attribute to pure fixes this issue – better would be dropping the & from char but that is an API change… Neither earlier g++ versions nor clang use this attribute to generate broken code, so we don't need a rebuild of dependencies or anything and g++-5 isn't even included in jessie, but the effect is so strange and apt popular enough to consider avoiding this problem anyhow. --- apt-pkg/contrib/strutl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 185cdc3fc..f4f80834b 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -79,7 +79,7 @@ bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); // split a given string by a char -std::vector VectorizeString(std::string const &haystack, char const &split) APT_CONST; +std::vector VectorizeString(std::string const &haystack, char const &split) APT_PURE; /* \brief Return a vector of strings from string "input" where "sep" * is used as the delimiter string. -- cgit v1.2.3 From b8eba208daebe3e3f235983e44da9c398d6f7a57 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 10 Mar 2015 14:11:54 +0100 Subject: reimplement the last uses of sprintf Working with strings c-style is complicated and error-prune, so by converting to c++ style we gain some simplicity and avoid buffer overflows by later extensions. Git-Dch: Ignore --- apt-pkg/contrib/cdromutl.cc | 31 +++++------ apt-pkg/contrib/strutl.cc | 126 +++++++++++++++++++------------------------- 2 files changed, 71 insertions(+), 86 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc index 936e377fb..6eb917457 100644 --- a/apt-pkg/contrib/cdromutl.cc +++ b/apt-pkg/contrib/cdromutl.cc @@ -207,7 +207,6 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) /* Run over the directory, we assume that the reader order will never change as the media is read-only. In theory if the kernel did some sort of wacked caching this might not be true.. */ - char S[300]; for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) { // Skip some files.. @@ -215,30 +214,32 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) strcmp(Dir->d_name,"..") == 0) continue; + std::string S; if (Version <= 1) { - sprintf(S,"%lu",(unsigned long)Dir->d_ino); + strprintf(S, "%lu", (unsigned long)Dir->d_ino); } else { struct stat Buf; if (stat(Dir->d_name,&Buf) != 0) continue; - sprintf(S,"%lu",(unsigned long)Buf.st_mtime); + strprintf(S, "%lu", (unsigned long)Buf.st_mtime); } - - Hash.Add(S); + + Hash.Add(S.c_str()); Hash.Add(Dir->d_name); }; - + if (chdir(StartDir.c_str()) != 0) { _error->Errno("chdir",_("Unable to change to %s"),StartDir.c_str()); closedir(D); return false; } closedir(D); - + // Some stats from the fsys + std::string S; if (_config->FindB("Debug::identcdrom",false) == false) { struct statvfs Buf; @@ -248,19 +249,19 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version) // We use a kilobyte block size to advoid overflow if (writable_media) { - sprintf(S,"%lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024))); + strprintf(S, "%lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024))); } else { - sprintf(S,"%lu %lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024)), - (long)(Buf.f_bfree*(Buf.f_bsize/1024))); + strprintf(S, "%lu %lu", (unsigned long)(Buf.f_blocks*(Buf.f_bsize/1024)), + (unsigned long)(Buf.f_bfree*(Buf.f_bsize/1024))); } - Hash.Add(S); - sprintf(S,"-%u",Version); + Hash.Add(S.c_str()); + strprintf(S, "-%u", Version); } else - sprintf(S,"-%u.debug",Version); - + strprintf(S, "-%u.debug", Version); + Res = Hash.Result().Value() + S; - return true; + return true; } /*}}}*/ // FindMountPointForDevice - Find mountpoint for the given device /*{{{*/ diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 0ac587a9e..0db4c57b2 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -324,21 +324,19 @@ bool ParseCWord(const char *&String,string &Res) /* */ string QuoteString(const string &Str, const char *Bad) { - string Res; + std::stringstream Res; for (string::const_iterator I = Str.begin(); I != Str.end(); ++I) { - if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || + if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || *I == 0x25 || // percent '%' char *I <= 0x20 || *I >= 0x7F) // control chars { - char Buf[10]; - sprintf(Buf,"%%%02x",(int)*I); - Res += Buf; + ioprintf(Res,"%%%02x",(int)*I); } else - Res += *I; + Res << *I; } - return Res; + return Res.str(); } /*}}}*/ // DeQuoteString - Convert a string from quoted from /*{{{*/ @@ -379,13 +377,12 @@ string DeQuoteString(string::const_iterator const &begin, YottaBytes (E24) */ string SizeToStr(double Size) { - char S[300]; double ASize; if (Size >= 0) ASize = Size; else ASize = -1*Size; - + /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes, ExaBytes, ZettaBytes, YottaBytes */ char Ext[] = {'\0','k','M','G','T','P','E','Z','Y'}; @@ -394,20 +391,21 @@ string SizeToStr(double Size) { if (ASize < 100 && I != 0) { - sprintf(S,"%'.1f %c",ASize,Ext[I]); - break; + std::string S; + strprintf(S, "%'.1f %c", ASize, Ext[I]); + return S; } - + if (ASize < 10000) { - sprintf(S,"%'.0f %c",ASize,Ext[I]); - break; + std::string S; + strprintf(S, "%'.0f %c", ASize, Ext[I]); + return S; } ASize /= 1000.0; I++; } - - return S; + return ""; } /*}}}*/ // TimeToStr - Convert the time into a string /*{{{*/ @@ -415,36 +413,27 @@ string SizeToStr(double Size) /* Converts a number of seconds to a hms format */ string TimeToStr(unsigned long Sec) { - char S[300]; - - while (1) + std::string S; + if (Sec > 60*60*24) { - if (Sec > 60*60*24) - { - //d means days, h means hours, min means minutes, s means seconds - sprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60); - break; - } - - if (Sec > 60*60) - { - //h means hours, min means minutes, s means seconds - sprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60); - break; - } - - if (Sec > 60) - { - //min means minutes, s means seconds - sprintf(S,_("%limin %lis"),Sec/60,Sec % 60); - break; - } - - //s means seconds - sprintf(S,_("%lis"),Sec); - break; + //TRANSLATOR: d means days, h means hours, min means minutes, s means seconds + strprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60); + } + else if (Sec > 60*60) + { + //TRANSLATOR: h means hours, min means minutes, s means seconds + strprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60); + } + else if (Sec > 60) + { + //TRANSLATOR: min means minutes, s means seconds + strprintf(S,_("%limin %lis"),Sec/60,Sec % 60); + } + else + { + //TRANSLATOR: s means seconds + strprintf(S,_("%lis"),Sec); } - return S; } /*}}}*/ @@ -1423,7 +1412,7 @@ size_t strv_length(const char **str_array) ; return i; } - + /*}}}*/ // DeEscapeString - unescape (\0XX and \xXX) from a string /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1605,51 +1594,46 @@ void URI::CopyFrom(const string &U) /* */ URI::operator string() { - string Res; - + std::stringstream Res; + if (Access.empty() == false) - Res = Access + ':'; - + Res << Access << ':'; + if (Host.empty() == false) - { + { if (Access.empty() == false) - Res += "//"; - + Res << "//"; + if (User.empty() == false) { // FIXME: Technically userinfo is permitted even less // characters than these, but this is not conveniently // expressed with a blacklist. - Res += QuoteString(User, ":/?#[]@"); + Res << QuoteString(User, ":/?#[]@"); if (Password.empty() == false) - Res += ":" + QuoteString(Password, ":/?#[]@"); - Res += "@"; + Res << ":" << QuoteString(Password, ":/?#[]@"); + Res << "@"; } - + // Add RFC 2732 escaping characters - if (Access.empty() == false && - (Host.find('/') != string::npos || Host.find(':') != string::npos)) - Res += '[' + Host + ']'; + if (Access.empty() == false && Host.find_first_of("/:") != string::npos) + Res << '[' << Host << ']'; else - Res += Host; - + Res << Host; + if (Port != 0) - { - char S[30]; - sprintf(S,":%u",Port); - Res += S; - } + Res << ':' << Port; } - + if (Path.empty() == false) { if (Path[0] != '/') - Res += "/" + Path; + Res << "/" << Path; else - Res += Path; + Res << Path; } - - return Res; + + return Res.str(); } /*}}}*/ // URI::SiteOnly - Return the schema and site for the URI /*{{{*/ -- cgit v1.2.3 From 76cbc9abb2d09ee5b248dfaa24948ba016fb6dee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 30 Mar 2015 14:37:43 +0200 Subject: if we can, use gccs __builtin_swap methods Git-Dch: Ignore --- apt-pkg/contrib/sha2_internal.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/sha2_internal.cc b/apt-pkg/contrib/sha2_internal.cc index 131ff5beb..f70b7b17d 100644 --- a/apt-pkg/contrib/sha2_internal.cc +++ b/apt-pkg/contrib/sha2_internal.cc @@ -129,6 +129,14 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +#define REVERSE32(w,x) { \ + (x) = __builtin_bswap32(w); \ +} +#define REVERSE64(w,x) { \ + (x) = __builtin_bswap64(w); \ +} +#else #define REVERSE32(w,x) { \ sha2_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ @@ -142,6 +150,7 @@ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } +#endif #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* -- cgit v1.2.3 From 9224ce3d4d1ea0428a70e75134998e08aa45b1e6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 30 Mar 2015 20:47:13 +0200 Subject: calculate only expected hashes in methods Methods get told which hashes are expected by the acquire system, which means we can use this list to restrict what we calculate in the methods as any extra we are calculating is wasted effort as we can't compare it with anything anyway. Adding support for a new hash algorithm is therefore 'free' now and if a algorithm is no longer provided in a repository for a file, we automatically stop calculating it. In practice this results in a speed-up in Debian as we don't have SHA512 here (so far), so we practically stop calculating it. --- apt-pkg/contrib/hashes.cc | 63 ++++++++++++++++++++++++++++++++++++----------- apt-pkg/contrib/hashes.h | 21 +++++++++++++--- 2 files changed, 65 insertions(+), 19 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 6e7080bc9..953465091 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -250,28 +250,34 @@ bool HashStringList::operator!=(HashStringList const &other) const class PrivateHashes { public: unsigned long long FileSize; + unsigned int CalcHashes; - PrivateHashes() : FileSize(0) {} + PrivateHashes(unsigned int const CalcHashes) : FileSize(0), CalcHashes(CalcHashes) {} }; /*}}}*/ // Hashes::Add* - Add the contents of data or FD /*{{{*/ -bool Hashes::Add(const unsigned char * const Data,unsigned long long const Size, unsigned int const Hashes) +bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size) { bool Res = true; APT_IGNORE_DEPRECATED_PUSH - if ((Hashes & MD5SUM) == MD5SUM) + if ((d->CalcHashes & MD5SUM) == MD5SUM) Res &= MD5.Add(Data, Size); - if ((Hashes & SHA1SUM) == SHA1SUM) + if ((d->CalcHashes & SHA1SUM) == SHA1SUM) Res &= SHA1.Add(Data, Size); - if ((Hashes & SHA256SUM) == SHA256SUM) + if ((d->CalcHashes & SHA256SUM) == SHA256SUM) Res &= SHA256.Add(Data, Size); - if ((Hashes & SHA512SUM) == SHA512SUM) + if ((d->CalcHashes & SHA512SUM) == SHA512SUM) Res &= SHA512.Add(Data, Size); APT_IGNORE_DEPRECATED_POP d->FileSize += Size; return Res; } -bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes) +bool Hashes::Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes) +{ + d->CalcHashes = Hashes; + return Add(Data, Size); +} +bool Hashes::AddFD(int const Fd,unsigned long long Size) { unsigned char Buf[64*64]; bool const ToEOF = (Size == UntilEOF); @@ -285,12 +291,17 @@ bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hash if (ToEOF && Res == 0) // EOF break; Size -= Res; - if (Add(Buf, Res, Hashes) == false) + if (Add(Buf, Res) == false) return false; } return true; } -bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes) +bool Hashes::AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes) +{ + d->CalcHashes = Hashes; + return AddFD(Fd, Size); +} +bool Hashes::AddFD(FileFd &Fd,unsigned long long Size) { unsigned char Buf[64*64]; bool const ToEOF = (Size == 0); @@ -309,20 +320,29 @@ bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes else if (a == 0) // EOF break; Size -= a; - if (Add(Buf, a, Hashes) == false) + if (Add(Buf, a) == false) return false; } return true; +} +bool Hashes::AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes) +{ + d->CalcHashes = Hashes; + return AddFD(Fd, Size); } /*}}}*/ HashStringList Hashes::GetHashStringList() { HashStringList hashes; APT_IGNORE_DEPRECATED_PUSH - hashes.push_back(HashString("MD5Sum", MD5.Result().Value())); - hashes.push_back(HashString("SHA1", SHA1.Result().Value())); - hashes.push_back(HashString("SHA256", SHA256.Result().Value())); - hashes.push_back(HashString("SHA512", SHA512.Result().Value())); + if ((d->CalcHashes & MD5SUM) == MD5SUM) + hashes.push_back(HashString("MD5Sum", MD5.Result().Value())); + if ((d->CalcHashes & SHA1SUM) == SHA1SUM) + hashes.push_back(HashString("SHA1", SHA1.Result().Value())); + if ((d->CalcHashes & SHA256SUM) == SHA256SUM) + hashes.push_back(HashString("SHA256", SHA256.Result().Value())); + if ((d->CalcHashes & SHA512SUM) == SHA512SUM) + hashes.push_back(HashString("SHA512", SHA512.Result().Value())); APT_IGNORE_DEPRECATED_POP std::string SizeStr; strprintf(SizeStr, "%llu", d->FileSize); @@ -330,6 +350,19 @@ APT_IGNORE_DEPRECATED_POP return hashes; } APT_IGNORE_DEPRECATED_PUSH -Hashes::Hashes() { d = new PrivateHashes(); } +Hashes::Hashes() { d = new PrivateHashes(~0); } +Hashes::Hashes(unsigned int const Hashes) { d = new PrivateHashes(Hashes); } +Hashes::Hashes(HashStringList const &Hashes) { + unsigned int calcHashes = Hashes.usable() ? 0 : ~0; + if (Hashes.find("MD5Sum") != NULL) + calcHashes |= MD5SUM; + if (Hashes.find("SHA1") != NULL) + calcHashes |= SHA1SUM; + if (Hashes.find("SHA256") != NULL) + calcHashes |= SHA256SUM; + if (Hashes.find("SHA512") != NULL) + calcHashes |= SHA512SUM; + d = new PrivateHashes(calcHashes); +} Hashes::~Hashes() { delete d; } APT_IGNORE_DEPRECATED_POP diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 154862457..ac13c8ace 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -178,7 +178,8 @@ class Hashes static const int UntilEOF = 0; - bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes = ~0); + bool Add(const unsigned char * const Data, unsigned long long const Size); + APT_DEPRECATED bool Add(const unsigned char * const Data, unsigned long long const Size, unsigned int const Hashes); inline bool Add(const char * const Data) {return Add((unsigned char const * const)Data,strlen(Data));}; inline bool Add(const unsigned char * const Beg,const unsigned char * const End) @@ -186,13 +187,24 @@ class Hashes enum SupportedHashes { MD5SUM = (1 << 0), SHA1SUM = (1 << 1), SHA256SUM = (1 << 2), SHA512SUM = (1 << 3) }; - bool AddFD(int const Fd,unsigned long long Size = 0, unsigned int const Hashes = ~0); - bool AddFD(FileFd &Fd,unsigned long long Size = 0, unsigned int const Hashes = ~0); + bool AddFD(int const Fd,unsigned long long Size = 0); + APT_DEPRECATED bool AddFD(int const Fd,unsigned long long Size, unsigned int const Hashes); + bool AddFD(FileFd &Fd,unsigned long long Size = 0); + APT_DEPRECATED bool AddFD(FileFd &Fd,unsigned long long Size, unsigned int const Hashes); HashStringList GetHashStringList(); APT_IGNORE_DEPRECATED_PUSH + /** create a Hashes object to calculate all supported hashes + * + * If ALL is too much, you can limit which Hashes are calculated + * with the following other constructors which mention explicitly + * which hashes to generate. */ Hashes(); + /** @param Hashes bitflag composed of #SupportedHashes */ + Hashes(unsigned int const Hashes); + /** @param Hashes is a list of hashes */ + Hashes(HashStringList const &Hashes); virtual ~Hashes(); APT_IGNORE_DEPRECATED_POP @@ -208,15 +220,16 @@ APT_IGNORE_DEPRECATED_POP } public: +APT_IGNORE_DEPRECATED_PUSH APT_DEPRECATED bool AddFD(int const Fd, unsigned long long Size, bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512) { return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512)); }; - APT_DEPRECATED bool AddFD(FileFd &Fd, unsigned long long Size, bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512) { return AddFD(Fd, Size, boolsToFlag(addMD5, addSHA1, addSHA256, addSHA512)); }; +APT_IGNORE_DEPRECATED_POP }; #endif -- cgit v1.2.3 From d84da4995df24329e96d57a22136683a9e370f4e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 11 Apr 2015 20:13:19 +0200 Subject: ensure lists/ files have correct permissions after apt-cdrom add Its a bit unpredictable which permissons and owners we will encounter on a CD-ROM (or a USB stick, as apt-cdrom is responsible for those too), so we have to ensure in this codepath as well that everything is nicely setup without waiting for a 'apt-get update' to fix up the (potential) mess. --- apt-pkg/contrib/fileutl.cc | 19 +++++++++++++++++++ apt-pkg/contrib/fileutl.h | 13 ++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 47033eadf..afc243b7f 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -874,6 +874,25 @@ bool StartsWithGPGClearTextSignature(string const &FileName) return true; } /*}}}*/ +// ChangeOwnerAndPermissionOfFile - set file attributes to requested values /*{{{*/ +bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode) +{ + if (strcmp(file, "/dev/null") == 0) + return true; + bool Res = true; + if (getuid() == 0 && strlen(user) != 0 && strlen(group) != 0) // if we aren't root, we can't chown, so don't try it + { + // ensure the file is owned by root and has good permissions + struct passwd const * const pw = getpwnam(user); + struct group const * const gr = getgrnam(group); + if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0) + Res &= _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file); + } + if (chmod(file, mode) != 0) + Res &= _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file); + return Res; +} + /*}}}*/ class FileFdPrivate { /*{{{*/ public: diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index a64d6cb98..97cb05c56 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -195,10 +195,21 @@ pid_t ExecFork(std::set keep_fds); void MergeKeepFdsFromConfiguration(std::set &keep_fds); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); - // check if the given file starts with a PGP cleartext signature bool StartsWithGPGClearTextSignature(std::string const &FileName); +/** change file attributes to requested known good values + * + * The method skips the user:group setting if not root. + * + * @param requester is printed as functionname in error cases + * @param file is the file to be modified + * @param user is the (new) owner of the file, e.g. _apt + * @param group is the (new) group owning the file, e.g. root + * @param mode is the access mode of the file, e.g. 0644 + */ +bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * const file, char const * const user, char const * const group, mode_t const mode); + /** * \brief Drop privileges * -- cgit v1.2.3 From 15901516326737a67f2a9af26cd7e434162de019 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 28 Apr 2015 17:55:00 +0200 Subject: Move sysconf(_SC_OPEN_MAX); out of the for() loop to avoid unneeded syscalls --- apt-pkg/contrib/fileutl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 1ba4674e5..1e6d96fe9 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -778,8 +778,9 @@ pid_t ExecFork(std::set KeepFDs) signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); + long ScOpenMax = sysconf(_SC_OPEN_MAX); // Close all of our FDs - just in case - for (int K = 3; K != sysconf(_SC_OPEN_MAX); K++) + for (int K = 3; K != ScOpenMax; K++) { if(KeepFDs.find(K) == KeepFDs.end()) fcntl(K,F_SETFD,FD_CLOEXEC); -- cgit v1.2.3 From ad5a4ac2bccb04f4aa74aeb2cefa90c79ed4b5e9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 9 May 2015 14:02:59 +0200 Subject: fix macro definition for very old GCC < 3 Git-Dch: Ignore --- apt-pkg/contrib/macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index 14541d4d8..2f9c6c269 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -89,7 +89,7 @@ #define APT_MUSTCHECK __attribute__((warn_unused_result)) #else #define APT_NONNULL(...) - #define APT_REQRET + #define APT_MUSTCHECK #endif #if APT_GCC_VERSION >= 0x0400 -- cgit v1.2.3 From 495b7a615a2d8f485beadf88c6ed298f5bbe50c2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 12 May 2015 11:18:17 +0200 Subject: implement VerifyFile as all-hashes check It isn't used much compared to what the methodname suggests, but in the remaining uses it can't hurt to check more than strictly necessary by calculating and verifying with all hashes we can compare with rather than "just" the best known hash. --- apt-pkg/contrib/hashes.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 953465091..0fa443b4a 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -204,15 +204,22 @@ bool HashStringList::push_back(const HashString &hashString) /*{{{*/ /*}}}*/ bool HashStringList::VerifyFile(std::string filename) const /*{{{*/ { - if (list.empty() == true) - return false; - HashString const * const hs = find(NULL); - if (hs == NULL || hs->VerifyFile(filename) == false) + if (usable() == false) return false; + + Hashes hashes(*this); + FileFd file(filename, FileFd::ReadOnly); HashString const * const hsf = find("Checksum-FileSize"); - if (hsf != NULL && hsf->VerifyFile(filename) == false) - return false; - return true; + if (hsf != NULL) + { + std::string fileSize; + strprintf(fileSize, "%llu", file.FileSize()); + if (hsf->HashValue() != fileSize) + return false; + } + hashes.AddFD(file); + HashStringList const hsl = hashes.GetHashStringList(); + return hsl == *this; } /*}}}*/ bool HashStringList::operator==(HashStringList const &other) const /*{{{*/ -- cgit v1.2.3 From 448c38bdcd72b52f11ec5f326f822cf57653f81c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 6 Jun 2015 12:28:00 +0200 Subject: rework hashsum verification in the acquire system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having every item having its own code to verify the file(s) it handles is an errorprune process and easy to break, especially if items move through various stages (download, uncompress, patching, …). With a giant rework we centralize (most of) the verification to have a better enforcement rate and (hopefully) less chance for bugs, but it breaks the ABI bigtime in exchange – and as we break it anyway, it is broken even harder. It shouldn't effect most frontends as they don't deal with the acquire system at all or implement their own items, but some do and will need to be patched (might be an opportunity to use apt on-board material). The theory is simple: Items implement methods to decide if hashes need to be checked (in this stage) and to return the expected hashes for this item (in this stage). The verification itself is done in worker message passing which has the benefit that a hashsum error is now a proper error for the acquire system rather than a Done() which is later revised to a Failed(). --- apt-pkg/contrib/hashes.cc | 10 ++++++++++ apt-pkg/contrib/hashes.h | 9 +++++++++ 2 files changed, 19 insertions(+) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 0fa443b4a..11a7e479b 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include /*}}}*/ @@ -178,6 +179,15 @@ HashString const * HashStringList::find(char const * const type) const /*{{{*/ return NULL; } /*}}}*/ +unsigned long long HashStringList::FileSize() const /*{{{*/ +{ + HashString const * const hsf = find("Checksum-FileSize"); + if (hsf == NULL) + return 0; + std::string const hv = hsf->HashValue(); + return strtoull(hv.c_str(), NULL, 10); +} + /*}}}*/ bool HashStringList::supported(char const * const type) /*{{{*/ { for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index ac13c8ace..176ce4faa 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -87,6 +87,15 @@ class HashStringList */ HashString const * find(char const * const type) const; HashString const * find(std::string const &type) const { return find(type.c_str()); } + + /** finds the filesize hash and returns it as number + * + * @return beware: if the size isn't known we return \b 0 here, + * just like we would do for an empty file. If that is a problem + * for you have to get the size manually out of the list. + */ + unsigned long long FileSize() const; + /** check if the given hash type is supported * * @param type to check -- cgit v1.2.3 From 4f51fd8636592a96aecf17c8bf4cfdb3ea2207cc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 8 Jun 2015 00:06:41 +0200 Subject: support hashes for compressed pdiff files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At the moment we only have hashes for the uncompressed pdiff files, but via the new '$HASH-Download' field in the .diff/Index hashes can be provided for the .gz compressed pdiff file, which apt will pick up now and use to verify the download. Now, we "just" need a buy in from the creators of repositories… --- apt-pkg/contrib/hashes.cc | 11 ++++++++--- apt-pkg/contrib/hashes.h | 7 +++++++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 11a7e479b..46cf0ba08 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -188,6 +188,13 @@ unsigned long long HashStringList::FileSize() const /*{{{*/ return strtoull(hv.c_str(), NULL, 10); } /*}}}*/ +bool HashStringList::FileSize(unsigned long long const Size) /*{{{*/ +{ + std::string size; + strprintf(size, "%llu", Size); + return push_back(HashString("Checksum-FileSize", size)); +} + /*}}}*/ bool HashStringList::supported(char const * const type) /*{{{*/ { for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) @@ -361,9 +368,7 @@ APT_IGNORE_DEPRECATED_PUSH if ((d->CalcHashes & SHA512SUM) == SHA512SUM) hashes.push_back(HashString("SHA512", SHA512.Result().Value())); APT_IGNORE_DEPRECATED_POP - std::string SizeStr; - strprintf(SizeStr, "%llu", d->FileSize); - hashes.push_back(HashString("Checksum-FileSize", SizeStr)); + hashes.FileSize(d->FileSize); return hashes; } APT_IGNORE_DEPRECATED_PUSH diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 176ce4faa..e8d84da9e 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -96,6 +96,13 @@ class HashStringList */ unsigned long long FileSize() const; + /** sets the filesize hash + * + * @param Size of the file + * @return @see #push_back + */ + bool FileSize(unsigned long long const Size); + /** check if the given hash type is supported * * @param type to check -- cgit v1.2.3 From 1e0f0f28e1025f42a8172eb72f3e87984eb2b939 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 9 Jun 2015 11:59:22 +0200 Subject: configureable acquire targets to download additional files First pass at making the acquire system capable of downloading files based on configuration rather than hardcoded entries. It is now possible to instruct 'deb' and 'deb-src' sources.list lines to download more than just Packages/Translation-* and Sources files. Details on how to do that can be found in the included documentation file. --- apt-pkg/contrib/configuration.cc | 4 ++-- apt-pkg/contrib/configuration.h | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc index 42e35d32a..2500ab631 100644 --- a/apt-pkg/contrib/configuration.cc +++ b/apt-pkg/contrib/configuration.cc @@ -259,7 +259,7 @@ vector Configuration::FindVector(const char *Name) const return FindVector(Name, ""); } #endif -vector Configuration::FindVector(const char *Name, std::string const &Default) const +vector Configuration::FindVector(const char *Name, std::string const &Default, bool const Keys) const { vector Vec; const Item *Top = Lookup(Name); @@ -272,7 +272,7 @@ vector Configuration::FindVector(const char *Name, std::string const &De Item *I = Top->Child; while(I != NULL) { - Vec.push_back(I->Value); + Vec.push_back(Keys ? I->Tag : I->Value); I = I->Next; } if (Vec.empty() == true) diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h index 8d7d51037..eacc26fda 100644 --- a/apt-pkg/contrib/configuration.h +++ b/apt-pkg/contrib/configuration.h @@ -84,15 +84,8 @@ class Configuration * * \param Name of the parent node * \param Default list of values separated by commas */ -#if APT_PKG_ABI >= 413 - std::vector FindVector(const char *Name, std::string const &Default = "") const; - std::vector FindVector(std::string const &Name, std::string const &Default = "") const { return FindVector(Name.c_str(), Default); }; -#else - std::vector FindVector(const char *Name, std::string const &Default) const; - std::vector FindVector(std::string const &Name, std::string const &Default) const { return FindVector(Name.c_str(), Default); }; - std::vector FindVector(const char *Name) const; - std::vector FindVector(std::string const &Name) const { return FindVector(Name.c_str(), ""); }; -#endif + std::vector FindVector(const char *Name, std::string const &Default = "", bool const Keys = false) const; + std::vector FindVector(std::string const &Name, std::string const &Default = "", bool const Keys = false) const { return FindVector(Name.c_str(), Default, Keys); }; int FindI(const char *Name,int const &Default = 0) const; int FindI(std::string const &Name,int const &Default = 0) const {return FindI(Name.c_str(),Default);}; -- cgit v1.2.3 From 1da3b7b8e15b642135b54684e70a0c271471f07a Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 11 Jun 2015 10:56:31 +0200 Subject: show URI.Path in all acquire item descriptions It is a rather strange sight that index items use SiteOnly which strips the Path, while e.g. deb files are downloaded with NoUserPassword which does not. Important to note here is that for the file transport Path is pretty important as there is no Host which would be displayed by Site, which always resulted in "interesting" unspecific errors for "file:". Adding a 'middle' ground between the two which does show the Path but potentially modifies it (it strips a pending / at the end if existing) solves this "file:" issue, syncs the output and in the end helps to identify which file is meant exactly in progress output and co as a single site can have multiple repositories in different paths. --- apt-pkg/contrib/strutl.cc | 15 +++++++++++---- apt-pkg/contrib/strutl.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'apt-pkg/contrib') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 0db4c57b2..5731b5a2b 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1637,8 +1637,6 @@ URI::operator string() } /*}}}*/ // URI::SiteOnly - Return the schema and site for the URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ string URI::SiteOnly(const string &URI) { ::URI U(URI); @@ -1648,9 +1646,18 @@ string URI::SiteOnly(const string &URI) return U; } /*}}}*/ +// URI::ArchiveOnly - Return the schema, site and cleaned path for the URI /*{{{*/ +string URI::ArchiveOnly(const string &URI) +{ + ::URI U(URI); + U.User.clear(); + U.Password.clear(); + if (U.Path.empty() == false && U.Path[U.Path.length() - 1] == '/') + U.Path.erase(U.Path.length() - 1); + return U; +} + /*}}}*/ // URI::NoUserPassword - Return the schema, site and path for the URI /*{{{*/ -// --------------------------------------------------------------------- -/* */ string URI::NoUserPassword(const string &URI) { ::URI U(URI); diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index d64270aaf..01bbfef72 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -167,6 +167,7 @@ class URI inline void operator =(const std::string &From) {CopyFrom(From);} inline bool empty() {return Access.empty();}; static std::string SiteOnly(const std::string &URI); + static std::string ArchiveOnly(const std::string &URI); static std::string NoUserPassword(const std::string &URI); URI(std::string Path) {CopyFrom(Path);} -- cgit v1.2.3