summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sdext/source/pdfimport/config/description.xml2
-rw-r--r--sdext/source/pdfimport/filterdet.cxx4
-rw-r--r--sdext/source/pdfimport/inc/pdfparse.hxx2
-rw-r--r--sdext/source/pdfimport/pdfparse/pdfentries.cxx147
-rw-r--r--sdext/source/pdfimport/pdfparse/pdfparse.cxx4
-rw-r--r--sdext/source/pdfimport/tree/drawtreevisiting.cxx11
-rw-r--r--sdext/source/pdfimport/tree/drawtreevisiting.hxx4
-rwxr-xr-xsdext/source/pdfimport/wrapper/wrapper.cxx52
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx19
-rw-r--r--xpdf/makefile.mk2
-rw-r--r--xpdf/xpdf-3.02-ooopwd.patch101
11 files changed, 310 insertions, 38 deletions
diff --git a/sdext/source/pdfimport/config/description.xml b/sdext/source/pdfimport/config/description.xml
index 1fdd3b28aea1..93cdecfc5e4d 100644
--- a/sdext/source/pdfimport/config/description.xml
+++ b/sdext/source/pdfimport/config/description.xml
@@ -16,7 +16,7 @@
</simple-license>
</registration>
- <version value="1.0.4" />
+ <version value="1.0.5" />
<platform value="UPDATED_SUPPORTED_PLATFORM" />
diff --git a/sdext/source/pdfimport/filterdet.cxx b/sdext/source/pdfimport/filterdet.cxx
index e9d58cfdb3b2..d5fcf30a803c 100644
--- a/sdext/source/pdfimport/filterdet.cxx
+++ b/sdext/source/pdfimport/filterdet.cxx
@@ -718,6 +718,8 @@ uno::Reference< io::XStream > getAdditionalStream( const rtl::OUString&
rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
RTL_TEXTENCODING_ISO_8859_1 );
bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ // trash password string on heap
+ rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
}
if( ! bAuthenticated )
{
@@ -745,6 +747,8 @@ uno::Reference< io::XStream > getAdditionalStream( const rtl::OUString&
rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
RTL_TEXTENCODING_ISO_8859_1 );
bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ // trash password string on heap
+ rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
} while( bEntered && ! bAuthenticated );
}
diff --git a/sdext/source/pdfimport/inc/pdfparse.hxx b/sdext/source/pdfimport/inc/pdfparse.hxx
index 4d19d9140a09..683c438bdf54 100644
--- a/sdext/source/pdfimport/inc/pdfparse.hxx
+++ b/sdext/source/pdfimport/inc/pdfparse.hxx
@@ -260,6 +260,8 @@ struct PDFFile : public PDFContainer
bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen,
sal_uInt8* pOutBuffer,
unsigned int nObject, unsigned int nGeneration ) const;
+
+ rtl::OUString getDecryptionKey() const;
};
struct PDFObject : public PDFContainer
diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx
index a2ff6b996ff2..e741d7499915 100644
--- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx
+++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx
@@ -32,6 +32,7 @@
#include <rtl/strbuf.hxx>
#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
#include <rtl/alloc.h>
#include <rtl/digest.h>
#include <rtl/cipher.h>
@@ -59,6 +60,8 @@ struct EmitImplData
XRefTable m_aXRefTable;
// container of all indirect objects (usually a PDFFile*)
const PDFContainer* m_pObjectContainer;
+ unsigned int m_nDecryptObject;
+ unsigned int m_nDecryptGeneration;
// returns true if the xref table was updated
bool insertXref( unsigned int nObject, unsigned int nGeneration, unsigned int nOffset )
@@ -80,7 +83,9 @@ struct EmitImplData
}
EmitImplData( const PDFContainer* pTopContainer ) :
- m_pObjectContainer( pTopContainer )
+ m_pObjectContainer( pTopContainer ),
+ m_nDecryptObject( 0 ),
+ m_nDecryptGeneration( 0 )
{}
~EmitImplData() {}
bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer,
@@ -89,6 +94,12 @@ struct EmitImplData
const PDFFile* pFile = dynamic_cast<const PDFFile*>(m_pObjectContainer);
return pFile ? pFile->decrypt( pInBuffer, nLen, pOutBuffer, nObject, nGeneration ) : false;
}
+
+ void setDecryptObject( unsigned int nObject, unsigned int nGeneration )
+ {
+ m_nDecryptObject = nObject;
+ m_nDecryptGeneration = nGeneration;
+ }
};
}
@@ -199,6 +210,46 @@ bool PDFString::emit( EmitContext& rWriteContext ) const
{
if( ! rWriteContext.write( " ", 1 ) )
return false;
+ EmitImplData* pEData = getEmitData( rWriteContext );
+ if( rWriteContext.m_bDecrypt && pEData && pEData->m_nDecryptObject )
+ {
+ OString aFiltered( getFilteredString() );
+ // decrypt inplace (evil since OString is supposed to be const
+ // however in this case we know that getFilteredString returned a singular string instance
+ pEData->decrypt( (sal_uInt8*)aFiltered.getStr(), aFiltered.getLength(),
+ (sal_uInt8*)aFiltered.getStr(),
+ pEData->m_nDecryptObject, pEData->m_nDecryptGeneration );
+ // check for string or hex string
+ const sal_Char* pStr = aFiltered.getStr();
+ if( aFiltered.getLength() > 1 &&
+ ( (pStr[0] == sal_Char(0xff) && pStr[1] == sal_Char(0xfe)) ||
+ (pStr[0] == sal_Char(0xfe) && pStr[1] == sal_Char(0xff)) ) )
+ {
+ static const char pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ if( ! rWriteContext.write( "<", 1 ) )
+ return false;
+ for( sal_Int32 i = 0; i < aFiltered.getLength(); i++ )
+ {
+ if( ! rWriteContext.write( pHexTab + ((sal_uInt32(pStr[i]) >> 4) & 0x0f), 1 ) )
+ return false;
+ if( ! rWriteContext.write( pHexTab + (sal_uInt32(pStr[i]) & 0x0f), 1 ) )
+ return false;
+ }
+ if( ! rWriteContext.write( ">", 1 ) )
+ return false;
+ }
+ else
+ {
+ if( ! rWriteContext.write( "(", 1 ) )
+ return false;
+ if( ! rWriteContext.write( aFiltered.getStr(), aFiltered.getLength() ) )
+ return false;
+ if( ! rWriteContext.write( ")", 1 ) )
+ return false;
+ }
+ return true;
+ }
return rWriteContext.write( m_aString.getStr(), m_aString.getLength() );
}
@@ -418,6 +469,15 @@ bool PDFContainer::emitSubElements( EmitContext& rWriteContext ) const
int nEle = m_aSubElements.size();
for( int i = 0; i < nEle; i++ )
{
+ if( rWriteContext.m_bDecrypt )
+ {
+ const PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]);
+ if( pName && pName->m_aName.equals( rtl::OString("Encrypt") ) )
+ {
+ i++;
+ continue;
+ }
+ }
if( ! m_aSubElements[i]->emit( rWriteContext ) )
return false;
}
@@ -735,7 +795,7 @@ bool PDFObject::writeStream( EmitContext& rWriteContext, const PDFFile* pParsedF
{
char* pStream = NULL;
unsigned int nBytes = 0;
- if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes )
+ if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes && rWriteContext.m_bDeflate )
{
sal_uInt8* pOutBytes = NULL;
sal_uInt32 nOutBytes = 0;
@@ -767,17 +827,27 @@ bool PDFObject::emit( EmitContext& rWriteContext ) const
if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) )
return false;
- if( rWriteContext.m_bDeflate && pEData )
+ if( pEData )
+ pEData->setDecryptObject( m_nNumber, m_nGeneration );
+ if( (rWriteContext.m_bDeflate || rWriteContext.m_bDecrypt) && pEData )
{
char* pStream = NULL;
unsigned int nBytes = 0;
- if( getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext )
- && pStream && nBytes )
+ bool bDeflate = getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext );
+ if( pStream && nBytes )
{
// unzip the stream
sal_uInt8* pOutBytes = NULL;
sal_uInt32 nOutBytes = 0;
- unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
+ if( bDeflate && rWriteContext.m_bDeflate )
+ unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes );
+ else
+ {
+ // nothing to deflate, but decryption has happened
+ pOutBytes = (sal_uInt8*)pStream;
+ nOutBytes = (sal_uInt32)nBytes;
+ }
+
if( nOutBytes )
{
// clone this object
@@ -785,8 +855,32 @@ bool PDFObject::emit( EmitContext& rWriteContext ) const
// set length in the dictionary to new stream length
PDFNumber* pNewLen = new PDFNumber( double(nOutBytes) );
pClone->m_pStream->m_pDict->insertValue( "Length", pNewLen );
- // delete flatedecode filter
- pClone->m_pStream->m_pDict->eraseValue( "Filter" );
+
+ if( bDeflate && rWriteContext.m_bDeflate )
+ {
+ // delete flatedecode filter
+ std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it =
+ pClone->m_pStream->m_pDict->m_aMap.find( "Filter" );
+ if( it != pClone->m_pStream->m_pDict->m_aMap.end() )
+ {
+ PDFName* pFilter = dynamic_cast<PDFName*>(it->second);
+ if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
+ pClone->m_pStream->m_pDict->eraseValue( "Filter" );
+ else
+ {
+ PDFArray* pArray = dynamic_cast<PDFArray*>(it->second);
+ if( pArray && ! pArray->m_aSubElements.empty() )
+ {
+ pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front());
+ if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) )
+ {
+ delete pFilter;
+ pArray->m_aSubElements.erase( pArray->m_aSubElements.begin() );
+ }
+ }
+ }
+ }
+ }
// write sub elements except stream
bool bRet = true;
@@ -805,17 +899,23 @@ bool PDFObject::emit( EmitContext& rWriteContext ) const
if( bRet )
bRet = rWriteContext.write( "\nendstream\nendobj\n", 18 );
rtl_freeMemory( pStream );
- rtl_freeMemory( pOutBytes );
+ if( pOutBytes != (sal_uInt8*)pStream )
+ rtl_freeMemory( pOutBytes );
+ if( pEData )
+ pEData->setDecryptObject( 0, 0 );
return bRet;
}
- rtl_freeMemory( pOutBytes );
+ if( pOutBytes != (sal_uInt8*)pStream )
+ rtl_freeMemory( pOutBytes );
}
rtl_freeMemory( pStream );
}
- if( ! emitSubElements( rWriteContext ) )
- return false;
- return rWriteContext.write( "\nendobj\n", 8 );
+ bool bRet = emitSubElements( rWriteContext ) &&
+ rWriteContext.write( "\nendobj\n", 8 );
+ if( pEData )
+ pEData->setDecryptObject( 0, 0 );
+ return bRet;
}
PDFEntry* PDFObject::clone() const
@@ -1178,6 +1278,23 @@ bool PDFFile::setupDecryptionData( const OString& rPwd ) const
return bValid;
}
+rtl::OUString PDFFile::getDecryptionKey() const
+{
+ rtl::OUStringBuffer aBuf( ENCRYPTION_KEY_LEN * 2 );
+ if( impl_getData()->m_bIsEncrypted )
+ {
+ for( sal_uInt32 i = 0; i < m_pData->m_nKeyLength; i++ )
+ {
+ static const sal_Unicode pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] >> 4) & 0x0f] );
+ aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] & 0x0f)] );
+ }
+
+ }
+ return aBuf.makeStringAndClear();
+}
+
PDFFileImplData* PDFFile::impl_getData() const
{
if( m_pData )
@@ -1304,13 +1421,13 @@ PDFFileImplData* PDFFile::impl_getData() const
if( pNum )
m_pData->m_nPEntry = static_cast<sal_uInt32>(static_cast<sal_Int32>(pNum->m_fValue));
#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "p entry is %p\n", m_pData->m_nPEntry );
+ fprintf( stderr, "p entry is %p\n", (void*)m_pData->m_nPEntry );
#endif
}
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "Encryption dict: sec handler: %s, version = %d, revision = %d, key length = %d\n",
pFilter ? OUStringToOString( pFilter->getFilteredName(), RTL_TEXTENCODING_UTF8 ).getStr() : "<unknown>",
- (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, m_pData->m_nKeyLength );
+ (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, (int)m_pData->m_nKeyLength );
#endif
break;
}
diff --git a/sdext/source/pdfimport/pdfparse/pdfparse.cxx b/sdext/source/pdfimport/pdfparse/pdfparse.cxx
index b3ffa64427dd..0e54005c6bd0 100644
--- a/sdext/source/pdfimport/pdfparse/pdfparse.cxx
+++ b/sdext/source/pdfimport/pdfparse/pdfparse.cxx
@@ -572,7 +572,7 @@ PDFEntry* PDFReader::read( const char* pBuffer, unsigned int nLen )
aInfo.stop, pBuffer, aInfo.stop - pBuffer,
aInfo.hit ? "true" : "false",
aInfo.full ? "true" : "false",
- aInfo.length );
+ (int)aInfo.length );
#endif
}
catch( parser_error<const char*, const char*>& rError )
@@ -650,7 +650,7 @@ PDFEntry* PDFReader::read( const char* pFileName )
aInfo.stop - file_start,
aInfo.hit ? "true" : "false",
aInfo.full ? "true" : "false",
- aInfo.length );
+ (int)aInfo.length );
#endif
}
catch( parser_error< const char*, file_iterator<> >& rError )
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.cxx b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
index 5f1bb429ce8a..c68af3c37d86 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.cxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.cxx
@@ -212,7 +212,9 @@ void DrawXmlEmitter::visit( ParagraphElement& elem, const std::list< Element* >:
void DrawXmlEmitter::fillFrameProps( DrawElement& rElem,
PropertyMap& rProps,
- const EmitContext& rEmitContext )
+ const EmitContext& rEmitContext,
+ bool bWasTransformed
+ )
{
double rel_x = rElem.x, rel_y = rElem.y;
@@ -223,7 +225,7 @@ void DrawXmlEmitter::fillFrameProps( DrawElement& rElem,
const GraphicsContext& rGC =
rEmitContext.rProcessor.getGraphicsContext( rElem.GCId );
- if( rGC.Transformation.isIdentity() )
+ if( rGC.Transformation.isIdentity() || bWasTransformed )
{
rProps[ USTR( "svg:x" ) ] = convertPixelToUnitString( rel_x );
rProps[ USTR( "svg:y" ) ] = convertPixelToUnitString( rel_y );
@@ -350,7 +352,10 @@ void DrawXmlEmitter::visit( PolyPolyElement& elem, const std::list< Element* >::
}
PropertyMap aProps;
- fillFrameProps( elem, aProps, m_rEmitContext );
+ // PDFIProcessor transforms geometrical objects, not images and text
+ // so we need to tell fillFrameProps here that the transformation for
+ // a PolyPolyElement was already applied (aside form translation)
+ fillFrameProps( elem, aProps, m_rEmitContext, true );
rtl::OUStringBuffer aBuf( 64 );
aBuf.appendAscii( "0 0 " );
aBuf.append( convPx2mmPrec2(elem.w)*100.0 );
diff --git a/sdext/source/pdfimport/tree/drawtreevisiting.hxx b/sdext/source/pdfimport/tree/drawtreevisiting.hxx
index b499db1ca811..75ce72eeaf79 100644
--- a/sdext/source/pdfimport/tree/drawtreevisiting.hxx
+++ b/sdext/source/pdfimport/tree/drawtreevisiting.hxx
@@ -101,7 +101,9 @@ namespace pdfi
void fillFrameProps( DrawElement& rElem,
PropertyMap& rProps,
- const EmitContext& rEmitContext );
+ const EmitContext& rEmitContext,
+ bool bWasTransformed = false
+ );
public:
const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& GetBreakIterator();
diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx
index 51817ce5eacf..daa7cd42b61e 100755
--- a/sdext/source/pdfimport/wrapper/wrapper.cxx
+++ b/sdext/source/pdfimport/wrapper/wrapper.cxx
@@ -158,6 +158,8 @@ class Parser
sal_Int32 m_nNextToken;
sal_Int32 m_nCharIndex;
+ const double minAreaThreshold;
+ const double minLineWidth;
::rtl::OString readNextToken();
void readInt32( sal_Int32& o_Value );
@@ -167,7 +169,7 @@ class Parser
double readDouble();
void readBinaryData( uno::Sequence<sal_Int8>& rBuf );
- uno::Reference<rendering::XPolyPolygon2D> readPath();
+ uno::Reference<rendering::XPolyPolygon2D> readPath( double* );
void readChar();
void readLineCap();
@@ -199,7 +201,9 @@ public:
m_aLine(),
m_aFontMap(101),
m_nNextToken(-1),
- m_nCharIndex(-1)
+ m_nCharIndex(-1),
+ minAreaThreshold( 300.0 ),
+ minLineWidth( 12 )
{}
void parseLine( const ::rtl::OString& rLine );
@@ -306,7 +310,7 @@ void Parser::readBinaryData( uno::Sequence<sal_Int8>& rBuf )
OSL_PRECOND(nRes==osl_File_E_None, "inconsistent data");
}
-uno::Reference<rendering::XPolyPolygon2D> Parser::readPath()
+uno::Reference<rendering::XPolyPolygon2D> Parser::readPath( double* pArea = NULL )
{
const rtl::OString aSubPathMarker( "subpath" );
@@ -366,6 +370,15 @@ uno::Reference<rendering::XPolyPolygon2D> Parser::readPath()
readNextToken();
}
+ if( pArea )
+ {
+ basegfx::B2DRange aRange( aResult.getB2DRange() );
+ if( aRange.getWidth() <= minLineWidth || aRange.getHeight() <= minLineWidth)
+ *pArea = 0.0;
+ else
+ *pArea = aRange.getWidth() * aRange.getHeight();
+ }
+
return static_cast<rendering::XLinePolyPolygon2D*>(
new basegfx::unotools::UnoPolyPolygon(aResult));
}
@@ -805,9 +818,25 @@ void Parser::parseLine( const ::rtl::OString& rLine )
case EOCLIPPATH:
m_pSink->intersectEoClip(readPath()); break;
case EOFILLPATH:
- m_pSink->eoFillPath(readPath()); break;
+ {
+ double area = 0.0;
+ uno::Reference<rendering::XPolyPolygon2D> path = readPath( &area );
+ m_pSink->eoFillPath(path);
+ // if area is smaller than required, add borders.
+ if(area < minAreaThreshold)
+ m_pSink->strokePath(path);
+ }
+ break;
case FILLPATH:
- m_pSink->fillPath(readPath()); break;
+ {
+ double area = 0.0;
+ uno::Reference<rendering::XPolyPolygon2D> path = readPath( &area );
+ m_pSink->fillPath(path);
+ // if area is smaller than required, add borders.
+ if(area < minAreaThreshold)
+ m_pSink->strokePath(path);
+ }
+ break;
case RESTORESTATE:
m_pSink->popState(); break;
case SAVESTATE:
@@ -913,6 +942,8 @@ static bool checkEncryption( const rtl::OUString&
rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
RTL_TEXTENCODING_ISO_8859_1 );
bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ // trash password string on heap
+ rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
}
if( bAuthenticated )
bSuccess = true;
@@ -927,12 +958,23 @@ static bool checkEncryption( const rtl::OUString&
rtl::OString aIsoPwd = rtl::OUStringToOString( io_rPwd,
RTL_TEXTENCODING_ISO_8859_1 );
bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
+ // trash password string on heap
+ rtl_zeroMemory( (void*)aIsoPwd.getStr(), aIsoPwd.getLength() );
} while( bEntered && ! bAuthenticated );
}
OSL_TRACE( "password: %s\n", bAuthenticated ? "matches" : "does not match" );
bSuccess = bAuthenticated;
}
+ // trash password string on heap
+ rtl_zeroMemory( (void*)io_rPwd.getStr(), io_rPwd.getLength()*sizeof(sal_Unicode) );
+ if( bAuthenticated )
+ {
+ rtl::OUStringBuffer aBuf( 128 );
+ aBuf.appendAscii( "_OOO_pdfi_Credentials_" );
+ aBuf.append( pPDFFile->getDecryptionKey() );
+ io_rPwd = aBuf.makeStringAndClear();
+ }
}
else
bSuccess = true;
diff --git a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
index 6011b6989576..e0c5763acac8 100644
--- a/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx
@@ -107,8 +107,8 @@ int main(int argc, char **argv)
#endif
// try to read a possible open password form stdin
- char aPwBuf[34];
- aPwBuf[33] = 0;
+ char aPwBuf[129];
+ aPwBuf[128] = 0;
if( ! fgets( aPwBuf, sizeof(aPwBuf)-1, stdin ) )
aPwBuf[0] = 0; // mark as empty
else
@@ -132,14 +132,14 @@ int main(int argc, char **argv)
// check for password string(s)
- GooString* pOwnerPasswordStr( ownerPassword[0] != '\001'
- ? new GooString(ownerPassword)
- : (GooString *)NULL );
- GooString* pUserPasswordStr( aPwBuf[0] != 0
+ GooString* pOwnerPasswordStr( aPwBuf[0] != 0
? new GooString( aPwBuf )
- : ( userPassword[0] != '\001'
- ? new GooString(userPassword)
- : (GooString *)NULL ) );
+ : (ownerPassword[0] != '\001'
+ ? new GooString(ownerPassword)
+ : (GooString *)NULL ) );
+ GooString* pUserPasswordStr( userPassword[0] != '\001'
+ ? new GooString(userPassword)
+ : (GooString *)NULL );
if( outputFile[0] != '\001' )
g_binary_out = fopen(outputFile,"wb");
@@ -188,7 +188,6 @@ int main(int argc, char **argv)
}
else
{
-
pdfi::PDFOutDev* pOutDev( new pdfi::PDFOutDev(&aDoc) );
// tell receiver early - needed for proper progress calculation
diff --git a/xpdf/makefile.mk b/xpdf/makefile.mk
index c3dea0f006d5..191eefd50e2b 100644
--- a/xpdf/makefile.mk
+++ b/xpdf/makefile.mk
@@ -48,7 +48,7 @@ dummy:
TARFILE_NAME=xpdf-3.02
TARFILE_MD5=599dc4cc65a07ee868cf92a667a913d2
-PATCH_FILES=$(TARFILE_NAME).patch
+PATCH_FILES=$(TARFILE_NAME).patch xpdf-3.02-ooopwd.patch
CONFIGURE_DIR=
BUILD_DIR=$(CONFIGURE_DIR)
diff --git a/xpdf/xpdf-3.02-ooopwd.patch b/xpdf/xpdf-3.02-ooopwd.patch
new file mode 100644
index 000000000000..f773585b3f91
--- /dev/null
+++ b/xpdf/xpdf-3.02-ooopwd.patch
@@ -0,0 +1,101 @@
+--- misc/xpdf-3.02/xpdf/SecurityHandler.cc 2007-02-27 23:05:52.000000000 +0100
++++ misc/build/xpdf-3.02/xpdf/SecurityHandler.cc 2011-02-03 16:41:49.000000000 +0100
+@@ -40,7 +40,7 @@
+
+ encryptDictA->dictLookup("Filter", &filterObj);
+ if (filterObj.isName("Standard")) {
+- secHdlr = new StandardSecurityHandler(docA, encryptDictA);
++ secHdlr = new OOoImportSecurityhandler(docA, encryptDictA);
+ } else if (filterObj.isName()) {
+ #ifdef ENABLE_PLUGINS
+ if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) {
+@@ -310,6 +310,60 @@
+ return gTrue;
+ }
+
++//------------------------------------------------------------------------
++// OOoImportSecurityhandler
++//------------------------------------------------------------------------
++
++OOoImportSecurityhandler::~OOoImportSecurityhandler()
++{
++}
++
++inline Guchar toNum( Guchar digit )
++{
++ return (digit >= '0') && digit <= '9'
++ ? digit - '0'
++ : (digit >= 'A' && digit <= 'F')
++ ? digit - 'A' + 10
++ : (digit >= 'a' && digit <= 'f')
++ ? digit - 'a' + 10
++ : Guchar(0xff);
++}
++
++GBool OOoImportSecurityhandler::authorize(void* authData)
++{
++ if( !ok )
++ return gFalse;
++ if( authData )
++ {
++ GString* ownerPassword = ((StandardAuthData *)authData)->ownerPassword;
++ if( ownerPassword )
++ {
++ const char* pStr = ownerPassword->getCString();
++ if( strncmp( pStr, "_OOO_pdfi_Credentials_", 22 ) == 0 )
++ {
++ // a hex encoded byte sequence should follow until end of string
++ // the length must match fileKeyLength
++ // if this is the case we can assume that the password checked out
++ // and the file key is valid
++ // max len is 16 (the size of the fileKey array)
++ pStr += 22;
++ size_t i = 0;
++ while( pStr[0] && pStr[1] && i < sizeof( fileKey ) )
++ {
++ fileKey[i++] = (toNum( *pStr++ ) << 4)
++ | (toNum( *pStr++ ));
++ }
++ if( i == size_t(fileKeyLength) )
++ {
++ ownerPasswordOk = gTrue;
++ return gTrue;
++ }
++ }
++ }
++ }
++ return StandardSecurityHandler::authorize( authData );
++}
++
+ #ifdef ENABLE_PLUGINS
+
+ //------------------------------------------------------------------------
+--- misc/xpdf-3.02/xpdf/SecurityHandler.h 2007-02-27 23:05:52.000000000 +0100
++++ misc/build/xpdf-3.02/xpdf/SecurityHandler.h 2011-02-03 16:26:17.000000000 +0100
+@@ -103,7 +103,7 @@
+ virtual int getEncVersion() { return encVersion; }
+ virtual CryptAlgorithm getEncAlgorithm() { return encAlgorithm; }
+
+-private:
++protected:
+
+ int permFlags;
+ GBool ownerPasswordOk;
+@@ -119,6 +119,17 @@
+ GBool ok;
+ };
+
++class OOoImportSecurityhandler : public StandardSecurityHandler
++{
++public:
++ OOoImportSecurityhandler( PDFDoc* docA, Object* encryptDictA )
++ : StandardSecurityHandler( docA, encryptDictA )
++ {}
++ virtual ~OOoImportSecurityhandler();
++
++ virtual GBool authorize(void* authData);
++};
++
+ #ifdef ENABLE_PLUGINS
+ //------------------------------------------------------------------------
+ // ExternalSecurityHandler