X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/eff0c22e59e65b6b63e854ff41eb091278e05714..4e99adb0d3727c0ae41edc9b3f52448d0d5b7655:/apt-pkg/tagfile.cc diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 3a3a3a04a..72dd475b3 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -98,7 +99,7 @@ public: }; /*}}}*/ -static unsigned long AlphaHash(const char *Text, size_t Length) /*{{{*/ +static unsigned long BetaHash(const char *Text, size_t Length) /*{{{*/ { /* This very simple hash function for the last 8 letters gives very good performance on the debian package files */ @@ -110,7 +111,7 @@ static unsigned long AlphaHash(const char *Text, size_t Length) /*{{{*/ unsigned long Res = 0; for (size_t i = 0; i < Length; ++i) Res = ((unsigned long)(Text[i]) & 0xDF) ^ (Res << 1); - return Res & 0xFF; + return Res & 0x7F; } /*}}}*/ @@ -214,7 +215,7 @@ bool pkgTagFile::Step(pkgTagSection &Tag) break; if (Resize() == false) - return _error->Error(_("Unable to parse package file %s (%d)"), + return _error->Warning(_("Unable to parse package file %s (%d)"), d->Fd->Name().c_str(), 1); } while (Tag.Scan(d->Start,d->End - d->Start, false) == false); @@ -300,7 +301,7 @@ static void RemoveCommentsFromBuffer(pkgTagFilePrivate * const d) std::vector> good_parts; while (current <= d->End) { - size_t const restLength = (d->End - current) + 1; + size_t const restLength = (d->End - current); if (d->isCommentedLine == false) { current = static_cast(memchr(current, '#', restLength)); @@ -335,7 +336,7 @@ static void RemoveCommentsFromBuffer(pkgTagFilePrivate * const d) } ++current; // is the next line a comment, too? - if (current > d->End || *current != '#') + if (current >= d->End || *current != '#') { d->chunks.emplace_back(false, (current - bad_start)); good_start = current; @@ -474,6 +475,7 @@ pkgTagSection::pkgTagSection() : Section(0), d(new pkgTagSectionPrivate()), Stop(0) { memset(&AlphaIndexes, 0, sizeof(AlphaIndexes)); + memset(&BetaIndexes, 0, sizeof(BetaIndexes)); } APT_IGNORE_DEPRECATED_POP /*}}}*/ @@ -499,6 +501,7 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R if (d->Tags.empty() == false) { memset(&AlphaIndexes, 0, sizeof(AlphaIndexes)); + memset(&BetaIndexes, 0, sizeof(BetaIndexes)); d->Tags.clear(); } d->Tags.reserve(0x100); @@ -510,7 +513,8 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R pkgTagSectionPrivate::TagData lastTagData(0); lastTagData.EndTag = 0; - unsigned long lastTagHash = 0; + Key lastTagKey = Key::Unknown; + unsigned int lastTagHash = 0; while (Stop < End) { TrimRecord(true,End); @@ -526,11 +530,15 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R // store the last found tag if (lastTagData.EndTag != 0) { - if (AlphaIndexes[lastTagHash] != 0) - lastTagData.NextInBucket = AlphaIndexes[lastTagHash]; - APT_IGNORE_DEPRECATED_PUSH - AlphaIndexes[lastTagHash] = TagCount; - APT_IGNORE_DEPRECATED_POP + if (lastTagKey != Key::Unknown) { + AlphaIndexes[static_cast(lastTagKey)] = TagCount; + } else { + if (BetaIndexes[lastTagHash] != 0) + lastTagData.NextInBucket = BetaIndexes[lastTagHash]; + APT_IGNORE_DEPRECATED_PUSH + BetaIndexes[lastTagHash] = TagCount; + APT_IGNORE_DEPRECATED_POP + } d->Tags.push_back(lastTagData); } @@ -547,7 +555,9 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R ; ++EndTag; lastTagData.EndTag = EndTag - Section; - lastTagHash = AlphaHash(Stop, EndTag - Stop); + lastTagKey = pkgTagHash(Stop, EndTag - Stop); + if (lastTagKey == Key::Unknown) + lastTagHash = BetaHash(Stop, EndTag - Stop); // find the beginning of the value Stop = Colon + 1; for (; Stop < End && isspace_ascii(*Stop) != 0; ++Stop) @@ -572,9 +582,13 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength, bool const R { if (lastTagData.EndTag != 0) { - if (AlphaIndexes[lastTagHash] != 0) - lastTagData.NextInBucket = AlphaIndexes[lastTagHash]; - APT_IGNORE_DEPRECATED(AlphaIndexes[lastTagHash] = TagCount;) + if (lastTagKey != Key::Unknown) { + AlphaIndexes[static_cast(lastTagKey)] = TagCount; + } else { + if (BetaIndexes[lastTagHash] != 0) + lastTagData.NextInBucket = BetaIndexes[lastTagHash]; + APT_IGNORE_DEPRECATED(BetaIndexes[lastTagHash] = TagCount;) + } d->Tags.push_back(lastTagData); } @@ -618,11 +632,21 @@ bool pkgTagSection::Exists(StringView Tag) const // TagSection::Find - Locate a tag /*{{{*/ // --------------------------------------------------------------------- /* This searches the section for a tag that matches the given string. */ +bool pkgTagSection::Find(Key key,unsigned int &Pos) const +{ + auto Bucket = AlphaIndexes[static_cast(key)]; + Pos = Bucket - 1; + return Bucket != 0; +} bool pkgTagSection::Find(StringView TagView,unsigned int &Pos) const { const char * const Tag = TagView.data(); size_t const Length = TagView.length(); - unsigned int Bucket = AlphaIndexes[AlphaHash(Tag, Length)]; + auto key = pkgTagHash(Tag, Length); + if (key != Key::Unknown) + return Find(key, Pos); + + unsigned int Bucket = BetaIndexes[BetaHash(Tag, Length)]; if (Bucket == 0) return false; @@ -643,13 +667,9 @@ bool pkgTagSection::Find(StringView TagView,unsigned int &Pos) const return false; } -bool pkgTagSection::Find(StringView Tag,const char *&Start, +bool pkgTagSection::FindInternal(unsigned int Pos, const char *&Start, const char *&End) const { - unsigned int Pos; - if (Find(Tag, Pos) == false) - return false; - Start = Section + d->Tags[Pos].StartValue; // Strip off the gunk from the end End = Section + d->Tags[Pos + 1].StartTag; @@ -659,6 +679,18 @@ bool pkgTagSection::Find(StringView Tag,const char *&Start, for (; isspace_ascii(End[-1]) != 0 && End > Start; --End); return true; +} +bool pkgTagSection::Find(StringView Tag,const char *&Start, + const char *&End) const +{ + unsigned int Pos; + return Find(Tag, Pos) && FindInternal(Pos, Start, End); +} +bool pkgTagSection::Find(Key key,const char *&Start, + const char *&End) const +{ + unsigned int Pos; + return Find(key, Pos) && FindInternal(Pos, Start, End); } /*}}}*/ // TagSection::FindS - Find a string /*{{{*/ @@ -669,15 +701,19 @@ StringView pkgTagSection::Find(StringView Tag) const if (Find(Tag,Start,End) == false) return StringView(); return StringView(Start, End - Start); +} +StringView pkgTagSection::Find(Key key) const +{ + const char *Start; + const char *End; + if (Find(key,Start,End) == false) + return StringView(); + return StringView(Start, End - Start); } /*}}}*/ // TagSection::FindRawS - Find a string /*{{{*/ -StringView pkgTagSection::FindRaw(StringView Tag) const +StringView pkgTagSection::FindRawInternal(unsigned int Pos) const { - unsigned int Pos; - if (Find(Tag, Pos) == false) - return ""; - char const *Start = (char const *) memchr(Section + d->Tags[Pos].EndTag, ':', d->Tags[Pos].StartValue - d->Tags[Pos].EndTag); ++Start; char const *End = Section + d->Tags[Pos + 1].StartTag; @@ -687,16 +723,26 @@ StringView pkgTagSection::FindRaw(StringView Tag) const for (; isspace_ascii(End[-1]) != 0 && End > Start; --End); return StringView(Start, End - Start); +} +StringView pkgTagSection::FindRaw(StringView Tag) const +{ + unsigned int Pos; + return Find(Tag, Pos) ? FindRawInternal(Pos) : ""; +} +StringView pkgTagSection::FindRaw(Key key) const +{ + unsigned int Pos; + return Find(key, Pos) ? FindRawInternal(Pos) : ""; } /*}}}*/ // TagSection::FindI - Find an integer /*{{{*/ // --------------------------------------------------------------------- /* */ -signed int pkgTagSection::FindI(StringView Tag,signed long Default) const +signed int pkgTagSection::FindIInternal(unsigned int Pos,signed long Default) const { const char *Start; const char *Stop; - if (Find(Tag,Start,Stop) == false) + if (FindInternal(Pos,Start,Stop) == false) return Default; // Copy it into a temp buffer so we can use strtol @@ -717,16 +763,28 @@ signed int pkgTagSection::FindI(StringView Tag,signed long Default) const if (S == End) return Default; return Result; +} +signed int pkgTagSection::FindI(Key key,signed long Default) const +{ + unsigned int Pos; + + return Find(key, Pos) ? FindIInternal(Pos) : Default; +} +signed int pkgTagSection::FindI(StringView Tag,signed long Default) const +{ + unsigned int Pos; + + return Find(Tag, Pos) ? FindIInternal(Pos, Default) : Default; } /*}}}*/ // TagSection::FindULL - Find an unsigned long long integer /*{{{*/ // --------------------------------------------------------------------- /* */ -unsigned long long pkgTagSection::FindULL(StringView Tag, unsigned long long const &Default) const +unsigned long long pkgTagSection::FindULLInternal(unsigned int Pos, unsigned long long const &Default) const { const char *Start; const char *Stop; - if (Find(Tag,Start,Stop) == false) + if (FindInternal(Pos,Start,Stop) == false) return Default; // Copy it into a temp buffer so we can use strtoull @@ -741,31 +799,69 @@ unsigned long long pkgTagSection::FindULL(StringView Tag, unsigned long long con if (S == End) return Default; return Result; +} +unsigned long long pkgTagSection::FindULL(Key key, unsigned long long const &Default) const +{ + unsigned int Pos; + + return Find(key, Pos) ? FindULLInternal(Pos, Default) : Default; +} +unsigned long long pkgTagSection::FindULL(StringView Tag, unsigned long long const &Default) const +{ + unsigned int Pos; + + return Find(Tag, Pos) ? FindULLInternal(Pos, Default) : Default; } /*}}}*/ // TagSection::FindB - Find boolean value /*{{{*/ // --------------------------------------------------------------------- /* */ -bool pkgTagSection::FindB(StringView Tag, bool Default) const +bool pkgTagSection::FindBInternal(unsigned int Pos, bool Default) const { const char *Start, *Stop; - if (Find(Tag, Start, Stop) == false) + if (FindInternal(Pos, Start, Stop) == false) return Default; return StringToBool(string(Start, Stop)); +} +bool pkgTagSection::FindB(Key key, bool Default) const +{ + unsigned int Pos; + return Find(key, Pos) ? FindBInternal(Pos, Default): Default; +} +bool pkgTagSection::FindB(StringView Tag, bool Default) const +{ + unsigned int Pos; + return Find(Tag, Pos) ? FindBInternal(Pos, Default) : Default; } /*}}}*/ // TagSection::FindFlag - Locate a yes/no type flag /*{{{*/ // --------------------------------------------------------------------- /* The bits marked in Flag are masked on/off in Flags */ -bool pkgTagSection::FindFlag(StringView Tag, uint8_t &Flags, +bool pkgTagSection::FindFlagInternal(unsigned int Pos, uint8_t &Flags, uint8_t const Flag) const { const char *Start; const char *Stop; - if (Find(Tag,Start,Stop) == false) + if (FindInternal(Pos,Start,Stop) == false) return true; return FindFlag(Flags, Flag, Start, Stop); } +bool pkgTagSection::FindFlag(Key key, uint8_t &Flags, + uint8_t const Flag) const +{ + unsigned int Pos; + if (Find(key,Pos) == false) + return true; + return FindFlagInternal(Pos, Flags, Flag); +} +bool pkgTagSection::FindFlag(StringView Tag, uint8_t &Flags, + uint8_t const Flag) const +{ + unsigned int Pos; + if (Find(Tag,Pos) == false) + return true; + return FindFlagInternal(Pos, Flags, Flag); +} bool pkgTagSection::FindFlag(uint8_t &Flags, uint8_t const Flag, char const* const Start, char const* const Stop) { @@ -785,15 +881,27 @@ bool pkgTagSection::FindFlag(uint8_t &Flags, uint8_t const Flag, } return true; } -bool pkgTagSection::FindFlag(StringView Tag,unsigned long &Flags, +bool pkgTagSection::FindFlagInternal(unsigned int Pos,unsigned long &Flags, unsigned long Flag) const { const char *Start; const char *Stop; - if (Find(Tag,Start,Stop) == false) + if (FindInternal(Pos,Start,Stop) == false) return true; return FindFlag(Flags, Flag, Start, Stop); } +bool pkgTagSection::FindFlag(Key key,unsigned long &Flags, + unsigned long Flag) const +{ + unsigned int Pos; + return Find(key, Pos) ? FindFlagInternal(Pos, Flags, Flag) : true; +} +bool pkgTagSection::FindFlag(StringView Tag,unsigned long &Flags, + unsigned long Flag) const +{ + unsigned int Pos; + return Find(Tag, Pos) ? FindFlagInternal(Pos, Flags, Flag) : true; +} bool pkgTagSection::FindFlag(unsigned long &Flags, unsigned long Flag, char const* Start, char const* Stop) {