Hi,
I think you have discovered a major problem in PoDoFo.
Only indirect objects have an owner set. Destinations are often direct objects
though, so there is no guarantee that GetOwner() will return something.
Therefore, I changed PdfDestination::GetPage() and added a parameter where you
can pass the owner as a PdfDocument or a PdfVecObjects. This should make the
usage more obvious and will hopefully solve your problem.
Sorry, for the troubles.
Best regards,
Dominik
On Wednesday, January 12, 2011 12:21:03 pm Matias wrote:
> Hi there
>
> Thought I'd keep you posted regarding the issue I had with reading PDF
> destinations from the names tree last week. I managed to fix the issue
> after realising that the issue is that the object returned with
> GetKey(PdfName("D")) from the destination object of interest in the Dests
> names tree had an uninitialised pointer to the owner. If I set the owner
> of the destination object's dictionary like this, the crash ended:
> destObjDict.GetKey(PdfName("D"))->SetOwner(&doc->GetObjects());
>
> Is this a bug, or have I missed something? Still don't know how I'd write
> the same code without crashing using the GetDestination() method of
> PdfAnnotation, instead of finding out the destination object by hand using
> the names tree.
>
>
> PdfDictionary dict = ann->GetObject()->GetDictionary();
>
> PdfObject *indirKey = ann->GetObject()->GetIndirectKey("Dest");
>
> PdfString str = indirKey->GetString();
>
> NSUInteger pageNumber = NSNotFound;
> if (namesTree->GetValue(PdfName("Dests"),str)) {
> PdfObject *destObj = namesTree->GetValue(PdfName("Dests"), str);
>
> if (destObj) {
> if (destObj->GetDataType() == ePdfDataType_Dictionary) {
> PdfDictionary destObjDict = destObj->GetDictionary();
>
> if (destObjDict.GetKey(PdfName("D")) != NULL) {
> destObjDict.GetKey(PdfName("D"))->SetOwner(&doc-
>GetObjects()); //this
> fixes the crash
>
> PdfDestination destination =
> PdfDestination(destObjDict.GetKey(PdfName("D"))); PdfPage *page =
> destination.GetPage();
>
> pageNumber = page->GetPageNumber();
> }
> }
> }
> } else {
> cerr << "Destination is null";
> }
>
> On 6 Jan 2011, at 17:54, Dominik Seichter wrote:
> > Hi Matias,
> >
> > You are obviously right! I fixed the implementation of
> > PdfNamesTree::HasValue. Does this change fix the first problem you
> > reported?
> >
> > Cheers,
> >
> > Dominik
> >
> > On Thursday, January 06, 2011 04:54:48 pm Matias wrote:
> >> I found a seeming bug in PdfNamesTree::HasValue whilst trying to debug
> >> this issue. As Leonard helpfully pointed out, I should drop the / from
> >> in front of the name. I put it there in confusion because HasValue
> >> returned false if I queried for the key name without the slash. Well,
> >> as it turns out, the definition of PdfNamesTree::HasValue is as
> >> follows:
> >>
> >> bool PdfNamesTree::HasValue( const PdfName & tree, const PdfString & key
> >> ) const {
> >>
> >> return ( this->GetValue( tree, key) == NULL );
> >>
> >> }
> >>
> >> Surely it should be != NULL ?
> >>
> >>> I have a PdfAnnotation* stored in a variable named ann. The destination
> >>> of this PDF annotation is a named object in the document (a page
> >>> object). I've checked that ann->HasDestination() returns true for it.
> >>> However, if I try the following, I get an EXC_BAD_ACCESS:
> >>> PdfDestination destination = ann->GetDestination();
> >>>
> >>> Furthermore, if I try and resolve the destination of the object in the
> >>> following way through the /Dests names tree of the document, I get a
> >>> NULL back:
> >>>
> >>> PdfDictionary dict = ann->GetObject()->GetDictionary();
> >>> PdfObject *indirKey = ann->GetObject()->GetIndirectKey("Dest");
> >>> cerr << indirKey->GetString().GetStringUtf8(); //returns the name of
> >>> the named object correctly
> >>>
> >>> PdfNamesTree *namesTree = doc->GetNamesTree();
> >>> PdfObject *dests = namesTree->GetDestsNode();
> >>> PdfString str = indirKey->GetString();
> >>> PdfObject *indirObj = dests->GetIndirectKey(str.GetStringUtf8());
> >>>
> >>> if (namesTree->HasValue(PdfName("/Dests"),str)) {
> >>>
> >>> PdfObject *destObj = namesTree->GetValue(PdfName("/Dests"),
> >>> indirKey->GetString());
> >>>
> >>> if (!destObj) {
> >>>
> >>> cerr << "Value is NULL!"; //this code is reached, and it
shouldn't?
> >>>
> >>> }
> >>>
> >>> }
> >>>
> >>> Any ideas of what I am doing wrong? Does this have something to do with
> >>> lazy loading and accessing an indirect key perhaps?
> >>> -----------------------------------------------------------------------
> >>> - ------ Learn how Oracle Real Application Clusters (RAC) One Node
> >>> allows customers to consolidate database storage, standardize their
> >>> database environment, and, should the need arise, upgrade to a full
> >>> multi-node Oracle RAC database without downtime or disruption
> >>> http://p.sf.net/sfu/oracle-sfdevnl
> >>> _______________________________________________
> >>> Podofo-users mailing list
> >>> [email protected]
> >>> https://lists.sourceforge.net/lists/listinfo/podofo-users
> >>
> >> ------------------------------------------------------------------------
> >> --- --- Learn how Oracle Real Application Clusters (RAC) One Node allows
> >> customers to consolidate database storage, standardize their database
> >> environment, and, should the need arise, upgrade to a full multi-node
> >> Oracle RAC database without downtime or disruption
> >> http://p.sf.net/sfu/oracle-sfdevnl
> >> _______________________________________________
> >> Podofo-users mailing list
> >> [email protected]
> >> https://lists.sourceforge.net/lists/listinfo/podofo-users
------------------------------------------------------------------------------
Protect Your Site and Customers from Malware Attacks
Learn about various malware tactics and how to avoid them. Understand
malware threats, the impact they can have on your business, and how you
can protect your company and customers by using code signing.
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users