Create ResourceFinder from NameWatcher in QPDFPageObjectHelper

This commit is contained in:
Jay Berkenbilt 2021-03-01 16:13:03 -05:00
parent b444ab3352
commit 37fcc5ff71
4 changed files with 67 additions and 37 deletions

View File

@ -8,6 +8,7 @@
#include <qpdf/QPDFMatrix.hh>
#include <qpdf/QIntC.hh>
#include <qpdf/QPDFAcroFormDocumentHelper.hh>
#include <qpdf/ResourceFinder.hh>
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<std::string> 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<std::string>& 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<std::string> 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);
}

38
libqpdf/ResourceFinder.cc Normal file
View File

@ -0,0 +1,38 @@
#include <qpdf/ResourceFinder.hh>
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<std::string> const&
ResourceFinder::getNames() const
{
return this->names;
}
bool
ResourceFinder::sawBad() const
{
return this->saw_bad;
}

View File

@ -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 \

View File

@ -0,0 +1,22 @@
#ifndef RESOURCEFINDER_HH
#define RESOURCEFINDER_HH
#include <qpdf/QPDFObjectHandle.hh>
class ResourceFinder: public QPDFObjectHandle::TokenFilter
{
public:
ResourceFinder();
virtual ~ResourceFinder() = default;
virtual void handleToken(QPDFTokenizer::Token const&) override;
std::set<std::string> const& getNames() const;
bool sawBad() const;
private:
std::string last_name;
std::set<std::string> names;
std::map<std::string, std::set<std::string>> names_by_resource_type;
bool saw_bad;
};
#endif // RESOURCEFINDER_HH