diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2011-03-07 13:55:23 +0100 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2011-03-07 13:55:23 +0100 |
commit | dff4613b22cf811fdeb732ed527e0b113c2259aa (patch) | |
tree | 2935dabcf053b38866a2208bdc1420a7ac600c01 | |
parent | 102638f7029beb44fc5d5b62417e118f9d04ea76 (diff) | |
parent | ab1e1cb9882cdd54d7bab8b7e57c0d4ea78f4a9d (diff) |
CWS-TOOLING: integrate CWS vcl119ooo/DEV300_m103ooo/DEV300_m102
-rw-r--r-- | sdext/source/pdfimport/config/description.xml | 2 | ||||
-rw-r--r-- | sdext/source/pdfimport/filterdet.cxx | 4 | ||||
-rw-r--r-- | sdext/source/pdfimport/inc/pdfparse.hxx | 2 | ||||
-rw-r--r-- | sdext/source/pdfimport/pdfparse/pdfentries.cxx | 147 | ||||
-rw-r--r-- | sdext/source/pdfimport/pdfparse/pdfparse.cxx | 4 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/drawtreevisiting.cxx | 11 | ||||
-rw-r--r-- | sdext/source/pdfimport/tree/drawtreevisiting.hxx | 4 | ||||
-rwxr-xr-x | sdext/source/pdfimport/wrapper/wrapper.cxx | 52 | ||||
-rw-r--r-- | sdext/source/pdfimport/xpdfwrapper/wrapper_gpl.cxx | 21 | ||||
-rw-r--r-- | xpdf/makefile.mk | 2 | ||||
-rw-r--r-- | xpdf/xpdf-3.02-ooopwd.patch | 101 |
11 files changed, 311 insertions, 39 deletions
diff --git a/sdext/source/pdfimport/config/description.xml b/sdext/source/pdfimport/config/description.xml index 4810fd6..f4b2633 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 cd10464..2cec8d8 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 5dd73c9..a0a58bb 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 96d2dab..b121a50 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 d8d64cb..9b8a8e7 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 5c8d359..7f4eaf6 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 9931d4b..fc190d7 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 cd89d8f..4445f22 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" ); @@ -365,6 +369,15 @@ uno::Reference<rendering::XPolyPolygon2D> Parser::readPath() if( m_nCharIndex != -1 ) 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 0bc92f6..ef34021 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,17 +132,17 @@ 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"); - + #ifdef WNT // Win actually modifies output for O_TEXT file mode, so need to // revert to binary here @@ -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 c3dea0f..191eefd 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 0000000..f773585 --- /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 |