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/QPDFMatrix.hh>
#include <qpdf/QIntC.hh> #include <qpdf/QIntC.hh>
#include <qpdf/QPDFAcroFormDocumentHelper.hh> #include <qpdf/QPDFAcroFormDocumentHelper.hh>
#include <qpdf/ResourceFinder.hh>
class ContentProvider: public QPDFObjectHandle::StreamDataProvider 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 bool
QPDFPageObjectHelper::removeUnreferencedResourcesHelper( QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
QPDFPageObjectHelper ph, std::set<std::string>& unresolved) QPDFPageObjectHelper ph, std::set<std::string>& unresolved)
@ -712,10 +681,10 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject");
} }
NameWatcher nw; ResourceFinder rf;
try try
{ {
ph.filterContents(&nw); ph.filterContents(&rf);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -725,7 +694,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
" from this object"); " from this object");
return false; return false;
} }
if (nw.saw_bad) if (rf.sawBad())
{ {
QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names"); QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names");
ph.oh.warnIfPossible( ph.oh.warnIfPossible(
@ -760,7 +729,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
} }
std::set<std::string> local_unresolved; std::set<std::string> local_unresolved;
for (auto const& name: nw.names) for (auto const& name: rf.getNames())
{ {
if (! known_names.count(name)) if (! known_names.count(name))
{ {
@ -804,7 +773,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper(
// xobject, so don't remove it. // xobject, so don't remove it.
QTC::TC("qpdf", "QPDFPageObjectHelper resolving unresolved"); QTC::TC("qpdf", "QPDFPageObjectHelper resolving unresolved");
} }
else if (! nw.names.count(key)) else if (! rf.getNames().count(key))
{ {
dict.removeKey(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/QTC.cc \
libqpdf/QUtil.cc \ libqpdf/QUtil.cc \
libqpdf/RC4.cc \ libqpdf/RC4.cc \
libqpdf/ResourceFinder.cc \
libqpdf/SecureRandomDataProvider.cc \ libqpdf/SecureRandomDataProvider.cc \
libqpdf/SF_FlateLzwDecode.cc \ libqpdf/SF_FlateLzwDecode.cc \
libqpdf/SparseOHArray.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