diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index 77343b6f..58144a3f 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -8,6 +8,7 @@ #include #include #include +#include class ContentProvider: public QPDFObjectHandle::StreamDataProvider { @@ -670,38 +671,6 @@ QPDFPageObjectHelper::addContentTokenFilter( } } -class NameWatcher: public QPDFObjectHandle::TokenFilter -{ - public: - NameWatcher() : - saw_bad(false) - { - } - virtual ~NameWatcher() - { - } - virtual void handleToken(QPDFTokenizer::Token const&); - std::set names; - bool saw_bad; -}; - -void -NameWatcher::handleToken(QPDFTokenizer::Token const& token) -{ - if (token.getType() == QPDFTokenizer::tt_name) - { - // Create a name object and get its name. This canonicalizes - // the representation of the name - this->names.insert( - QPDFObjectHandle::newName(token.getValue()).getName()); - } - else if (token.getType() == QPDFTokenizer::tt_bad) - { - saw_bad = true; - } - writeToken(token); -} - bool QPDFPageObjectHelper::removeUnreferencedResourcesHelper( QPDFPageObjectHelper ph, std::set& unresolved) @@ -712,10 +681,10 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); } - NameWatcher nw; + ResourceFinder rf; try { - ph.filterContents(&nw); + ph.filterContents(&rf); } catch (std::exception& e) { @@ -725,7 +694,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( " from this object"); return false; } - if (nw.saw_bad) + if (rf.sawBad()) { QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names"); ph.oh.warnIfPossible( @@ -760,7 +729,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( } std::set local_unresolved; - for (auto const& name: nw.names) + for (auto const& name: rf.getNames()) { if (! known_names.count(name)) { @@ -804,7 +773,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( // xobject, so don't remove it. QTC::TC("qpdf", "QPDFPageObjectHelper resolving unresolved"); } - else if (! nw.names.count(key)) + else if (! rf.getNames().count(key)) { dict.removeKey(key); } diff --git a/libqpdf/ResourceFinder.cc b/libqpdf/ResourceFinder.cc new file mode 100644 index 00000000..74ba671f --- /dev/null +++ b/libqpdf/ResourceFinder.cc @@ -0,0 +1,38 @@ +#include + +ResourceFinder::ResourceFinder() : + saw_bad(false) +{ +} + +void +ResourceFinder::handleToken(QPDFTokenizer::Token const& token) +{ + if ((token.getType() == QPDFTokenizer::tt_word) && + (! this->last_name.empty())) + { + this->names.insert(this->last_name); + } + else if (token.getType() == QPDFTokenizer::tt_name) + { + this->last_name = + QPDFObjectHandle::newName(token.getValue()).getName(); + } + else if (token.getType() == QPDFTokenizer::tt_bad) + { + saw_bad = true; + } + writeToken(token); +} + +std::set const& +ResourceFinder::getNames() const +{ + return this->names; +} + +bool +ResourceFinder::sawBad() const +{ + return this->saw_bad; +} diff --git a/libqpdf/build.mk b/libqpdf/build.mk index f453e58e..9f935566 100644 --- a/libqpdf/build.mk +++ b/libqpdf/build.mk @@ -98,6 +98,7 @@ SRCS_libqpdf = \ libqpdf/QTC.cc \ libqpdf/QUtil.cc \ libqpdf/RC4.cc \ + libqpdf/ResourceFinder.cc \ libqpdf/SecureRandomDataProvider.cc \ libqpdf/SF_FlateLzwDecode.cc \ libqpdf/SparseOHArray.cc \ diff --git a/libqpdf/qpdf/ResourceFinder.hh b/libqpdf/qpdf/ResourceFinder.hh new file mode 100644 index 00000000..0ac74eab --- /dev/null +++ b/libqpdf/qpdf/ResourceFinder.hh @@ -0,0 +1,22 @@ +#ifndef RESOURCEFINDER_HH +#define RESOURCEFINDER_HH + +#include + +class ResourceFinder: public QPDFObjectHandle::TokenFilter +{ + public: + ResourceFinder(); + virtual ~ResourceFinder() = default; + virtual void handleToken(QPDFTokenizer::Token const&) override; + std::set const& getNames() const; + bool sawBad() const; + + private: + std::string last_name; + std::set names; + std::map> names_by_resource_type; + bool saw_bad; +}; + +#endif // RESOURCEFINDER_HH