Dom,

I'm struggling to determine what, exactly, the characteristics of the
pdf_long type are supposed to be.

It's defined as ptrdiff_t in trunk, but it's used in contexts that have
nothing to do with pointers or their comparison, such as reading offsets
from PDF files using sscanf. There, the format given is:

#ifdef _WIN64
            sscanf( m_buffer.GetBuffer(), "%10I64d %5ld %c \n",
                    &(m_offsets[objID].lOffset),
                    &(m_offsets[objID].lGeneration),
                    &(m_offsets[objID].cUsed) );
#else
            sscanf( m_buffer.GetBuffer(), "%10lld %5ld %c \n",
                    &(m_offsets[objID].lOffset),
                    &(m_offsets[objID].lGeneration),
                    &(m_offsets[objID].cUsed) );
#endif


where m_offsets[x] is a:

    struct TXRefEntry {
        inline TXRefEntry() : lOffset(0), lGeneration(0), cUsed('\x00'),
                              bParsed(false) { }
        pdf_long lOffset;
        long lGeneration;
        char cUsed;
        bool bParsed;
    };


so our formats are:

WIN64:
  "%10I64d %5ld %c"          ptrdiff_t,  long,  char,
  sizeof(type):              8           4      1

Other:
  "%10lld %5ld %c"           ptrdiff_t,  long,  char
   sizeof(type)              VARIES      VARIES 1
   sizeof(type) on ia32:     4           4      1
   sizeof(type) on x86_64:   8           8      1


In other words, a bit of a mess. As things stand, on 32-bit platforms
we're reading a 64-bit quantity into a 32-bit field = potential splat.
We generally get away with it (clearly we need better test cases) but
it's not safe.

podofo-clean/src/PdfParser.cpp: In member function ‘void
PoDoFo::PdfParser::ReadXRefSubsection(long long int&, long long int&)’:
warning: format ‘%10lld’ expects type ‘long long int*’, but argument 3
has type ‘ptrdiff_t*’



ptrdiff_t is not the same size on different platforms. It's 4 bytes on
32-bit platforms, and 8 bytes on 64-bit platforms.

I presume you've defined it to get around issues with win64's (bizarre)
decision to keep sizeof(long) = sizeof(int) = 4 where the whole rest of
the world went to sizeof(long) = sizeof(long long) = 8 .

Does it need to be an unsigned 4 byte quantity, or an unsigned 8 byte
quantity? Is it used in more than one place for different purposes when
we should have different typedefs for that?

What about the usage of "long" in TXRefEntry? Shouldn't it be a
uint32_t ?

-- 
Craig Ringer


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to