From 914c6e75b7f7f9c5d1f24bf721ee46e3d0aecbb8 Mon Sep 17 00:00:00 2001 From: Peter Edwards Date: Wed, 8 May 2024 20:25:24 +0100 Subject: [PATCH] Sanitize FileEntries iterator behaviour Only fetch data from iterator when using operator *, or when operator++ if we have not already fetched. --- dead.cc | 8 +++++--- libpstack/proc.h | 12 +++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/dead.cc b/dead.cc index 3978370..ab3ae07 100644 --- a/dead.cc +++ b/dead.cc @@ -193,7 +193,6 @@ CoreProcess::getPID() const FileEntries::iterator::iterator(const FileEntries &entries, ReaderArray::iterator pos) : entries(entries) , entriesIterator(pos) { - fetch(); } struct NamedEntry { @@ -205,14 +204,17 @@ struct NamedEntry { void FileEntries::iterator::fetch() { - if (entries.names) + if (!fetched && entries.names) { cur = std::make_pair(entries.names->readString(nameoff), *entriesIterator); + fetched = true; + } } FileEntries::iterator &FileEntries::iterator::operator++() { + fetch(); ++entriesIterator; nameoff += cur.first.size() + 1; - fetch(); + fetched = false; return *this; } diff --git a/libpstack/proc.h b/libpstack/proc.h index c06107b..7d5796c 100644 --- a/libpstack/proc.h +++ b/libpstack/proc.h @@ -435,15 +435,17 @@ class FileEntries { public: class iterator { + friend class FileEntries; const FileEntries &entries; void fetch(); + bool fetched = false; size_t nameoff = 0; std::pair cur; ReaderArray::iterator entriesIterator; public: iterator(const FileEntries &entries, ReaderArray::iterator start); iterator &operator++(); - std::pair operator *() { return cur; } + std::pair operator *() { fetch(); return cur; } bool operator != (const iterator &rhs) const { return entriesIterator != rhs.entriesIterator; } }; FileEntries(const Elf::Object &obj) { @@ -461,8 +463,12 @@ class FileEntries { entries = std::make_shared(); entriesArray = std::make_unique>(*entries); } - iterator begin() const { return iterator(*this, entriesArray->begin()); } - iterator end() const { return iterator(*this, entriesArray->end()); } + iterator begin() const { + return iterator(*this, entriesArray->begin()); + } + iterator end() const { + return iterator(*this, entriesArray->end()); + } };