1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sdext.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <pdfparse.hxx> 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 34*cdf0e10cSrcweir #include <rtl/ustring.hxx> 35*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 36*cdf0e10cSrcweir #include <rtl/alloc.h> 37*cdf0e10cSrcweir #include <rtl/digest.h> 38*cdf0e10cSrcweir #include <rtl/cipher.h> 39*cdf0e10cSrcweir #include <rtl/memory.h> 40*cdf0e10cSrcweir #ifdef SYSTEM_ZLIB 41*cdf0e10cSrcweir #include "zlib.h" 42*cdf0e10cSrcweir #else 43*cdf0e10cSrcweir #include <zlib/zlib.h> 44*cdf0e10cSrcweir #endif 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir #include <math.h> 47*cdf0e10cSrcweir #include <map> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include <stdio.h> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir using namespace rtl; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir namespace pdfparse 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir struct EmitImplData 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir // xref table: maps object number to a pair of (generation, buffer offset) 59*cdf0e10cSrcweir typedef std::map< unsigned int, std::pair< unsigned int, unsigned int > > XRefTable; 60*cdf0e10cSrcweir XRefTable m_aXRefTable; 61*cdf0e10cSrcweir // container of all indirect objects (usually a PDFFile*) 62*cdf0e10cSrcweir const PDFContainer* m_pObjectContainer; 63*cdf0e10cSrcweir unsigned int m_nDecryptObject; 64*cdf0e10cSrcweir unsigned int m_nDecryptGeneration; 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir // returns true if the xref table was updated 67*cdf0e10cSrcweir bool insertXref( unsigned int nObject, unsigned int nGeneration, unsigned int nOffset ) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir XRefTable::iterator it = m_aXRefTable.find( nObject ); 70*cdf0e10cSrcweir if( it == m_aXRefTable.end() ) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir // new entry 73*cdf0e10cSrcweir m_aXRefTable[ nObject ] = std::pair<unsigned int, unsigned int>(nGeneration,nOffset); 74*cdf0e10cSrcweir return true; 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir // update old entry, if generation number is higher 77*cdf0e10cSrcweir if( it->second.first < nGeneration ) 78*cdf0e10cSrcweir { 79*cdf0e10cSrcweir it->second = std::pair<unsigned int, unsigned int>(nGeneration,nOffset); 80*cdf0e10cSrcweir return true; 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir return false; 83*cdf0e10cSrcweir } 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir EmitImplData( const PDFContainer* pTopContainer ) : 86*cdf0e10cSrcweir m_pObjectContainer( pTopContainer ), 87*cdf0e10cSrcweir m_nDecryptObject( 0 ), 88*cdf0e10cSrcweir m_nDecryptGeneration( 0 ) 89*cdf0e10cSrcweir {} 90*cdf0e10cSrcweir ~EmitImplData() {} 91*cdf0e10cSrcweir bool decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer, 92*cdf0e10cSrcweir unsigned int nObject, unsigned int nGeneration ) const 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir const PDFFile* pFile = dynamic_cast<const PDFFile*>(m_pObjectContainer); 95*cdf0e10cSrcweir return pFile ? pFile->decrypt( pInBuffer, nLen, pOutBuffer, nObject, nGeneration ) : false; 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir void setDecryptObject( unsigned int nObject, unsigned int nGeneration ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir m_nDecryptObject = nObject; 101*cdf0e10cSrcweir m_nDecryptGeneration = nGeneration; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir }; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir using namespace pdfparse; 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir EmitContext::EmitContext( const PDFContainer* pTop ) : 110*cdf0e10cSrcweir m_bDeflate( false ), 111*cdf0e10cSrcweir m_bDecrypt( false ), 112*cdf0e10cSrcweir m_pImplData( NULL ) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir if( pTop ) 115*cdf0e10cSrcweir m_pImplData = new EmitImplData( pTop ); 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir EmitContext::~EmitContext() 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir delete m_pImplData; 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir PDFEntry::~PDFEntry() 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir EmitImplData* PDFEntry::getEmitData( EmitContext& rContext ) const 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir return rContext.m_pImplData; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir void PDFEntry::setEmitData( EmitContext& rContext, EmitImplData* pNewEmitData ) const 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir if( rContext.m_pImplData && rContext.m_pImplData != pNewEmitData ) 135*cdf0e10cSrcweir delete rContext.m_pImplData; 136*cdf0e10cSrcweir rContext.m_pImplData = pNewEmitData; 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir PDFValue::~PDFValue() 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir PDFComment::~PDFComment() 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir bool PDFComment::emit( EmitContext& rWriteContext ) const 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir return rWriteContext.write( m_aComment.getStr(), m_aComment.getLength() ); 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir PDFEntry* PDFComment::clone() const 153*cdf0e10cSrcweir { 154*cdf0e10cSrcweir return new PDFComment( m_aComment ); 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir PDFName::~PDFName() 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir } 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir bool PDFName::emit( EmitContext& rWriteContext ) const 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir if( ! rWriteContext.write( " /", 2 ) ) 164*cdf0e10cSrcweir return false; 165*cdf0e10cSrcweir return rWriteContext.write( m_aName.getStr(), m_aName.getLength() ); 166*cdf0e10cSrcweir } 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir PDFEntry* PDFName::clone() const 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir return new PDFName( m_aName ); 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir OUString PDFName::getFilteredName() const 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir OStringBuffer aFilter( m_aName.getLength() ); 176*cdf0e10cSrcweir const sal_Char* pStr = m_aName.getStr(); 177*cdf0e10cSrcweir unsigned int nLen = m_aName.getLength(); 178*cdf0e10cSrcweir for( unsigned int i = 0; i < nLen; i++ ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir if( pStr[i] == '#' && i < nLen - 3 ) 181*cdf0e10cSrcweir { 182*cdf0e10cSrcweir sal_Char rResult = 0; 183*cdf0e10cSrcweir i++; 184*cdf0e10cSrcweir if( pStr[i] >= '0' && pStr[i] <= '9' ) 185*cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'0' ) << 4; 186*cdf0e10cSrcweir else if( pStr[i] >= 'a' && pStr[i] <= 'f' ) 187*cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'a' + 10 ) << 4; 188*cdf0e10cSrcweir else if( pStr[i] >= 'A' && pStr[i] <= 'F' ) 189*cdf0e10cSrcweir rResult = sal_Char( pStr[i]-'A' + 10 ) << 4; 190*cdf0e10cSrcweir i++; 191*cdf0e10cSrcweir if( pStr[i] >= '0' && pStr[i] <= '9' ) 192*cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'0' ); 193*cdf0e10cSrcweir else if( pStr[i] >= 'a' && pStr[i] <= 'f' ) 194*cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'a' + 10 ); 195*cdf0e10cSrcweir else if( pStr[i] >= 'A' && pStr[i] <= 'F' ) 196*cdf0e10cSrcweir rResult |= sal_Char( pStr[i]-'A' + 10 ); 197*cdf0e10cSrcweir aFilter.append( rResult ); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir else 200*cdf0e10cSrcweir aFilter.append( pStr[i] ); 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir return OStringToOUString( aFilter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir PDFString::~PDFString() 206*cdf0e10cSrcweir { 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir bool PDFString::emit( EmitContext& rWriteContext ) const 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir if( ! rWriteContext.write( " ", 1 ) ) 212*cdf0e10cSrcweir return false; 213*cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext ); 214*cdf0e10cSrcweir if( rWriteContext.m_bDecrypt && pEData && pEData->m_nDecryptObject ) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir OString aFiltered( getFilteredString() ); 217*cdf0e10cSrcweir // decrypt inplace (evil since OString is supposed to be const 218*cdf0e10cSrcweir // however in this case we know that getFilteredString returned a singular string instance 219*cdf0e10cSrcweir pEData->decrypt( (sal_uInt8*)aFiltered.getStr(), aFiltered.getLength(), 220*cdf0e10cSrcweir (sal_uInt8*)aFiltered.getStr(), 221*cdf0e10cSrcweir pEData->m_nDecryptObject, pEData->m_nDecryptGeneration ); 222*cdf0e10cSrcweir // check for string or hex string 223*cdf0e10cSrcweir const sal_Char* pStr = aFiltered.getStr(); 224*cdf0e10cSrcweir if( aFiltered.getLength() > 1 && 225*cdf0e10cSrcweir ( (pStr[0] == sal_Char(0xff) && pStr[1] == sal_Char(0xfe)) || 226*cdf0e10cSrcweir (pStr[0] == sal_Char(0xfe) && pStr[1] == sal_Char(0xff)) ) ) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir static const char pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7', 229*cdf0e10cSrcweir '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 230*cdf0e10cSrcweir if( ! rWriteContext.write( "<", 1 ) ) 231*cdf0e10cSrcweir return false; 232*cdf0e10cSrcweir for( sal_Int32 i = 0; i < aFiltered.getLength(); i++ ) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir if( ! rWriteContext.write( pHexTab + ((sal_uInt32(pStr[i]) >> 4) & 0x0f), 1 ) ) 235*cdf0e10cSrcweir return false; 236*cdf0e10cSrcweir if( ! rWriteContext.write( pHexTab + (sal_uInt32(pStr[i]) & 0x0f), 1 ) ) 237*cdf0e10cSrcweir return false; 238*cdf0e10cSrcweir } 239*cdf0e10cSrcweir if( ! rWriteContext.write( ">", 1 ) ) 240*cdf0e10cSrcweir return false; 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir else 243*cdf0e10cSrcweir { 244*cdf0e10cSrcweir if( ! rWriteContext.write( "(", 1 ) ) 245*cdf0e10cSrcweir return false; 246*cdf0e10cSrcweir if( ! rWriteContext.write( aFiltered.getStr(), aFiltered.getLength() ) ) 247*cdf0e10cSrcweir return false; 248*cdf0e10cSrcweir if( ! rWriteContext.write( ")", 1 ) ) 249*cdf0e10cSrcweir return false; 250*cdf0e10cSrcweir } 251*cdf0e10cSrcweir return true; 252*cdf0e10cSrcweir } 253*cdf0e10cSrcweir return rWriteContext.write( m_aString.getStr(), m_aString.getLength() ); 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir PDFEntry* PDFString::clone() const 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir return new PDFString( m_aString ); 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir OString PDFString::getFilteredString() const 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir int nLen = m_aString.getLength(); 264*cdf0e10cSrcweir OStringBuffer aBuf( nLen ); 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir const sal_Char* pStr = m_aString.getStr(); 267*cdf0e10cSrcweir if( *pStr == '(' ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir const sal_Char* pRun = pStr+1; 270*cdf0e10cSrcweir while( pRun - pStr < nLen-1 ) 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir if( *pRun == '\\' ) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir pRun++; 275*cdf0e10cSrcweir if( pRun - pStr < nLen ) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir sal_Char aEsc = 0; 278*cdf0e10cSrcweir if( *pRun == 'n' ) 279*cdf0e10cSrcweir aEsc = '\n'; 280*cdf0e10cSrcweir else if( *pRun == 'r' ) 281*cdf0e10cSrcweir aEsc = '\r'; 282*cdf0e10cSrcweir else if( *pRun == 't' ) 283*cdf0e10cSrcweir aEsc = '\t'; 284*cdf0e10cSrcweir else if( *pRun == 'b' ) 285*cdf0e10cSrcweir aEsc = '\b'; 286*cdf0e10cSrcweir else if( *pRun == 'f' ) 287*cdf0e10cSrcweir aEsc = '\f'; 288*cdf0e10cSrcweir else if( *pRun == '(' ) 289*cdf0e10cSrcweir aEsc = '('; 290*cdf0e10cSrcweir else if( *pRun == ')' ) 291*cdf0e10cSrcweir aEsc = ')'; 292*cdf0e10cSrcweir else if( *pRun == '\\' ) 293*cdf0e10cSrcweir aEsc = '\\'; 294*cdf0e10cSrcweir else if( *pRun == '\n' ) 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir pRun++; 297*cdf0e10cSrcweir continue; 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir else if( *pRun == '\r' ) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir pRun++; 302*cdf0e10cSrcweir if( *pRun == '\n' ) 303*cdf0e10cSrcweir pRun++; 304*cdf0e10cSrcweir continue; 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir else 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir int i = 0; 309*cdf0e10cSrcweir while( i++ < 3 && *pRun >= '0' && *pRun <= '7' ) 310*cdf0e10cSrcweir aEsc = 8*aEsc + (*pRun++ - '0'); 311*cdf0e10cSrcweir // move pointer back to last character of octal sequence 312*cdf0e10cSrcweir pRun--; 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir aBuf.append( aEsc ); 315*cdf0e10cSrcweir } 316*cdf0e10cSrcweir } 317*cdf0e10cSrcweir else 318*cdf0e10cSrcweir aBuf.append( *pRun ); 319*cdf0e10cSrcweir // move pointer to next character 320*cdf0e10cSrcweir pRun++; 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir else if( *pStr == '<' ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir const sal_Char* pRun = pStr+1; 326*cdf0e10cSrcweir while( *pRun != '>' && pRun - pStr < nLen ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir sal_Char rResult = 0; 329*cdf0e10cSrcweir if( *pRun >= '0' && *pRun <= '9' ) 330*cdf0e10cSrcweir rResult = sal_Char( *pRun-'0' ) << 4; 331*cdf0e10cSrcweir else if( *pRun >= 'a' && *pRun <= 'f' ) 332*cdf0e10cSrcweir rResult = sal_Char( *pRun-'a' + 10 ) << 4; 333*cdf0e10cSrcweir else if( *pRun >= 'A' && *pRun <= 'F' ) 334*cdf0e10cSrcweir rResult = sal_Char( *pRun-'A' + 10 ) << 4; 335*cdf0e10cSrcweir pRun++; 336*cdf0e10cSrcweir if( *pRun != '>' && pRun - pStr < nLen ) 337*cdf0e10cSrcweir { 338*cdf0e10cSrcweir if( *pRun >= '0' && *pRun <= '9' ) 339*cdf0e10cSrcweir rResult |= sal_Char( *pRun-'0' ); 340*cdf0e10cSrcweir else if( *pRun >= 'a' && *pRun <= 'f' ) 341*cdf0e10cSrcweir rResult |= sal_Char( *pRun-'a' + 10 ); 342*cdf0e10cSrcweir else if( *pRun >= 'A' && *pRun <= 'F' ) 343*cdf0e10cSrcweir rResult |= sal_Char( *pRun-'A' + 10 ); 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir pRun++; 346*cdf0e10cSrcweir aBuf.append( rResult ); 347*cdf0e10cSrcweir } 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir return aBuf.makeStringAndClear(); 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir PDFNumber::~PDFNumber() 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir bool PDFNumber::emit( EmitContext& rWriteContext ) const 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir rtl::OStringBuffer aBuf( 32 ); 360*cdf0e10cSrcweir aBuf.append( ' ' ); 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir double fValue = m_fValue; 363*cdf0e10cSrcweir bool bNeg = false; 364*cdf0e10cSrcweir int nPrecision = 5; 365*cdf0e10cSrcweir if( fValue < 0.0 ) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir bNeg = true; 368*cdf0e10cSrcweir fValue=-fValue; 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir sal_Int64 nInt = (sal_Int64)fValue; 372*cdf0e10cSrcweir fValue -= (double)nInt; 373*cdf0e10cSrcweir // optimizing hardware may lead to a value of 1.0 after the subtraction 374*cdf0e10cSrcweir if( fValue == 1.0 || log10( 1.0-fValue ) <= -nPrecision ) 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir nInt++; 377*cdf0e10cSrcweir fValue = 0.0; 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir sal_Int64 nFrac = 0; 380*cdf0e10cSrcweir if( fValue ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir fValue *= pow( 10.0, (double)nPrecision ); 383*cdf0e10cSrcweir nFrac = (sal_Int64)fValue; 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir if( bNeg && ( nInt || nFrac ) ) 386*cdf0e10cSrcweir aBuf.append( '-' ); 387*cdf0e10cSrcweir aBuf.append( nInt ); 388*cdf0e10cSrcweir if( nFrac ) 389*cdf0e10cSrcweir { 390*cdf0e10cSrcweir int i; 391*cdf0e10cSrcweir aBuf.append( '.' ); 392*cdf0e10cSrcweir sal_Int64 nBound = (sal_Int64)(pow( 10.0, nPrecision - 1.0 )+0.5); 393*cdf0e10cSrcweir for ( i = 0; ( i < nPrecision ) && nFrac; i++ ) 394*cdf0e10cSrcweir { 395*cdf0e10cSrcweir sal_Int64 nNumb = nFrac / nBound; 396*cdf0e10cSrcweir nFrac -= nNumb * nBound; 397*cdf0e10cSrcweir aBuf.append( nNumb ); 398*cdf0e10cSrcweir nBound /= 10; 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir } 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir return rWriteContext.write( aBuf.getStr(), aBuf.getLength() ); 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir PDFEntry* PDFNumber::clone() const 406*cdf0e10cSrcweir { 407*cdf0e10cSrcweir return new PDFNumber( m_fValue ); 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir PDFBool::~PDFBool() 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir bool PDFBool::emit( EmitContext& rWriteContext ) const 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir return m_bValue ? rWriteContext.write( " true", 5 ) : rWriteContext.write( " false", 6 ); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir PDFEntry* PDFBool::clone() const 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir return new PDFBool( m_bValue ); 423*cdf0e10cSrcweir } 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir PDFNull::~PDFNull() 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir bool PDFNull::emit( EmitContext& rWriteContext ) const 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir return rWriteContext.write( " null", 5 ); 432*cdf0e10cSrcweir } 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir PDFEntry* PDFNull::clone() const 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir return new PDFNull(); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir PDFObjectRef::~PDFObjectRef() 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir bool PDFObjectRef::emit( EmitContext& rWriteContext ) const 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir OStringBuffer aBuf( 16 ); 447*cdf0e10cSrcweir aBuf.append( ' ' ); 448*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nNumber ) ); 449*cdf0e10cSrcweir aBuf.append( ' ' ); 450*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nGeneration ) ); 451*cdf0e10cSrcweir aBuf.append( " R", 2 ); 452*cdf0e10cSrcweir return rWriteContext.write( aBuf.getStr(), aBuf.getLength() ); 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir PDFEntry* PDFObjectRef::clone() const 456*cdf0e10cSrcweir { 457*cdf0e10cSrcweir return new PDFObjectRef( m_nNumber, m_nGeneration ); 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir PDFContainer::~PDFContainer() 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir int nEle = m_aSubElements.size(); 463*cdf0e10cSrcweir for( int i = 0; i < nEle; i++ ) 464*cdf0e10cSrcweir delete m_aSubElements[i]; 465*cdf0e10cSrcweir } 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir bool PDFContainer::emitSubElements( EmitContext& rWriteContext ) const 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir int nEle = m_aSubElements.size(); 470*cdf0e10cSrcweir for( int i = 0; i < nEle; i++ ) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir if( rWriteContext.m_bDecrypt ) 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir const PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]); 475*cdf0e10cSrcweir if( pName && pName->m_aName.equals( rtl::OString("Encrypt") ) ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir i++; 478*cdf0e10cSrcweir continue; 479*cdf0e10cSrcweir } 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir if( ! m_aSubElements[i]->emit( rWriteContext ) ) 482*cdf0e10cSrcweir return false; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir return true; 485*cdf0e10cSrcweir } 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir void PDFContainer::cloneSubElements( std::vector<PDFEntry*>& rNewSubElements ) const 488*cdf0e10cSrcweir { 489*cdf0e10cSrcweir int nEle = m_aSubElements.size(); 490*cdf0e10cSrcweir for( int i = 0; i < nEle; i++ ) 491*cdf0e10cSrcweir rNewSubElements.push_back( m_aSubElements[i]->clone() ); 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir PDFObject* PDFContainer::findObject( unsigned int nNumber, unsigned int nGeneration ) const 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size(); 497*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ ) 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir PDFObject* pObject = dynamic_cast<PDFObject*>(m_aSubElements[i]); 500*cdf0e10cSrcweir if( pObject && 501*cdf0e10cSrcweir pObject->m_nNumber == nNumber && 502*cdf0e10cSrcweir pObject->m_nGeneration == nGeneration ) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir return pObject; 505*cdf0e10cSrcweir } 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir return NULL; 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir 510*cdf0e10cSrcweir PDFArray::~PDFArray() 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir bool PDFArray::emit( EmitContext& rWriteContext ) const 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir if( ! rWriteContext.write( "[", 1 ) ) 517*cdf0e10cSrcweir return false; 518*cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) ) 519*cdf0e10cSrcweir return false; 520*cdf0e10cSrcweir return rWriteContext.write( "]", 1 ); 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir PDFEntry* PDFArray::clone() const 524*cdf0e10cSrcweir { 525*cdf0e10cSrcweir PDFArray* pNewAr = new PDFArray(); 526*cdf0e10cSrcweir cloneSubElements( pNewAr->m_aSubElements ); 527*cdf0e10cSrcweir return pNewAr; 528*cdf0e10cSrcweir } 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir PDFDict::~PDFDict() 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir } 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir bool PDFDict::emit( EmitContext& rWriteContext ) const 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir if( ! rWriteContext.write( "<<\n", 3 ) ) 537*cdf0e10cSrcweir return false; 538*cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) ) 539*cdf0e10cSrcweir return false; 540*cdf0e10cSrcweir return rWriteContext.write( "\n>>\n", 4 ); 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir void PDFDict::insertValue( const OString& rName, PDFEntry* pValue ) 544*cdf0e10cSrcweir { 545*cdf0e10cSrcweir if( ! pValue ) 546*cdf0e10cSrcweir eraseValue( rName ); 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::iterator it = m_aMap.find( rName ); 549*cdf0e10cSrcweir if( it == m_aMap.end() ) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir // new name/value, pair, append it 552*cdf0e10cSrcweir m_aSubElements.push_back( new PDFName( rName ) ); 553*cdf0e10cSrcweir m_aSubElements.push_back( pValue ); 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir else 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir unsigned int nSub = m_aSubElements.size(); 558*cdf0e10cSrcweir for( unsigned int i = 0; i < nSub; i++ ) 559*cdf0e10cSrcweir if( m_aSubElements[i] == it->second ) 560*cdf0e10cSrcweir m_aSubElements[i] = pValue; 561*cdf0e10cSrcweir delete it->second; 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir m_aMap[ rName ] = pValue; 564*cdf0e10cSrcweir } 565*cdf0e10cSrcweir 566*cdf0e10cSrcweir void PDFDict::eraseValue( const OString& rName ) 567*cdf0e10cSrcweir { 568*cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size(); 569*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ ) 570*cdf0e10cSrcweir { 571*cdf0e10cSrcweir PDFName* pName = dynamic_cast<PDFName*>(m_aSubElements[i]); 572*cdf0e10cSrcweir if( pName && pName->m_aName.equals( rName ) ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir for( unsigned int j = i+1; j < nEle; j++ ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir if( dynamic_cast<PDFComment*>(m_aSubElements[j]) == NULL ) 577*cdf0e10cSrcweir { 578*cdf0e10cSrcweir // free name and value 579*cdf0e10cSrcweir delete m_aSubElements[j]; 580*cdf0e10cSrcweir delete m_aSubElements[i]; 581*cdf0e10cSrcweir // remove subelements from vector 582*cdf0e10cSrcweir m_aSubElements.erase( m_aSubElements.begin()+j ); 583*cdf0e10cSrcweir m_aSubElements.erase( m_aSubElements.begin()+i ); 584*cdf0e10cSrcweir buildMap(); 585*cdf0e10cSrcweir return; 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir } 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir PDFEntry* PDFDict::buildMap() 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir // clear map 595*cdf0e10cSrcweir m_aMap.clear(); 596*cdf0e10cSrcweir // build map 597*cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size(); 598*cdf0e10cSrcweir PDFName* pName = NULL; 599*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ ) 600*cdf0e10cSrcweir { 601*cdf0e10cSrcweir if( dynamic_cast<PDFComment*>(m_aSubElements[i]) == NULL ) 602*cdf0e10cSrcweir { 603*cdf0e10cSrcweir if( pName ) 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir m_aMap[ pName->m_aName ] = m_aSubElements[i]; 606*cdf0e10cSrcweir pName = NULL; 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir else if( (pName = dynamic_cast<PDFName*>(m_aSubElements[i])) == NULL ) 609*cdf0e10cSrcweir return m_aSubElements[i]; 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir return pName; 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir 615*cdf0e10cSrcweir PDFEntry* PDFDict::clone() const 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir PDFDict* pNewDict = new PDFDict(); 618*cdf0e10cSrcweir cloneSubElements( pNewDict->m_aSubElements ); 619*cdf0e10cSrcweir pNewDict->buildMap(); 620*cdf0e10cSrcweir return pNewDict; 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir PDFStream::~PDFStream() 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir bool PDFStream::emit( EmitContext& rWriteContext ) const 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir return rWriteContext.copyOrigBytes( m_nBeginOffset, m_nEndOffset-m_nBeginOffset ); 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir PDFEntry* PDFStream::clone() const 633*cdf0e10cSrcweir { 634*cdf0e10cSrcweir return new PDFStream( m_nBeginOffset, m_nEndOffset, NULL ); 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir unsigned int PDFStream::getDictLength( const PDFContainer* pContainer ) const 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir if( ! m_pDict ) 640*cdf0e10cSrcweir return 0; 641*cdf0e10cSrcweir // find /Length entry, can either be a direct or indirect number object 642*cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it = 643*cdf0e10cSrcweir m_pDict->m_aMap.find( "Length" ); 644*cdf0e10cSrcweir if( it == m_pDict->m_aMap.end() ) 645*cdf0e10cSrcweir return 0; 646*cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(it->second); 647*cdf0e10cSrcweir if( ! pNum && pContainer ) 648*cdf0e10cSrcweir { 649*cdf0e10cSrcweir PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(it->second); 650*cdf0e10cSrcweir if( pRef ) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir int nEle = pContainer->m_aSubElements.size(); 653*cdf0e10cSrcweir for( int i = 0; i < nEle && ! pNum; i++ ) 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir PDFObject* pObj = dynamic_cast<PDFObject*>(pContainer->m_aSubElements[i]); 656*cdf0e10cSrcweir if( pObj && 657*cdf0e10cSrcweir pObj->m_nNumber == pRef->m_nNumber && 658*cdf0e10cSrcweir pObj->m_nGeneration == pRef->m_nGeneration ) 659*cdf0e10cSrcweir { 660*cdf0e10cSrcweir if( pObj->m_pObject ) 661*cdf0e10cSrcweir pNum = dynamic_cast<PDFNumber*>(pObj->m_pObject); 662*cdf0e10cSrcweir break; 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir } 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir return pNum ? static_cast<unsigned int>(pNum->m_fValue) : 0; 668*cdf0e10cSrcweir } 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir PDFObject::~PDFObject() 671*cdf0e10cSrcweir { 672*cdf0e10cSrcweir } 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir bool PDFObject::getDeflatedStream( char** ppStream, unsigned int* pBytes, const PDFContainer* pObjectContainer, EmitContext& rContext ) const 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir bool bIsDeflated = false; 677*cdf0e10cSrcweir if( m_pStream && m_pStream->m_pDict && 678*cdf0e10cSrcweir m_pStream->m_nEndOffset > m_pStream->m_nBeginOffset+15 679*cdf0e10cSrcweir ) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir unsigned int nOuterStreamLen = m_pStream->m_nEndOffset - m_pStream->m_nBeginOffset; 682*cdf0e10cSrcweir *ppStream = static_cast<char*>(rtl_allocateMemory( nOuterStreamLen )); 683*cdf0e10cSrcweir if( ! ppStream ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir *pBytes = 0; 686*cdf0e10cSrcweir return false; 687*cdf0e10cSrcweir } 688*cdf0e10cSrcweir unsigned int nRead = rContext.readOrigBytes( m_pStream->m_nBeginOffset, nOuterStreamLen, *ppStream ); 689*cdf0e10cSrcweir if( nRead != nOuterStreamLen ) 690*cdf0e10cSrcweir { 691*cdf0e10cSrcweir rtl_freeMemory( *ppStream ); 692*cdf0e10cSrcweir *ppStream = NULL; 693*cdf0e10cSrcweir *pBytes = 0; 694*cdf0e10cSrcweir return false; 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir // is there a filter entry ? 697*cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it = 698*cdf0e10cSrcweir m_pStream->m_pDict->m_aMap.find( "Filter" ); 699*cdf0e10cSrcweir if( it != m_pStream->m_pDict->m_aMap.end() ) 700*cdf0e10cSrcweir { 701*cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(it->second); 702*cdf0e10cSrcweir if( ! pFilter ) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir PDFArray* pArray = dynamic_cast<PDFArray*>(it->second); 705*cdf0e10cSrcweir if( pArray && ! pArray->m_aSubElements.empty() ) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front()); 708*cdf0e10cSrcweir } 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir // is the (first) filter FlateDecode ? 712*cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) ) 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir bIsDeflated = true; 715*cdf0e10cSrcweir } 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir // prepare compressed data section 718*cdf0e10cSrcweir char* pStream = *ppStream; 719*cdf0e10cSrcweir if( pStream[0] == 's' ) 720*cdf0e10cSrcweir pStream += 6; // skip "stream" 721*cdf0e10cSrcweir // skip line end after "stream" 722*cdf0e10cSrcweir while( *pStream == '\r' || *pStream == '\n' ) 723*cdf0e10cSrcweir pStream++; 724*cdf0e10cSrcweir // get the compressed length 725*cdf0e10cSrcweir *pBytes = m_pStream->getDictLength( pObjectContainer ); 726*cdf0e10cSrcweir if( pStream != *ppStream ) 727*cdf0e10cSrcweir rtl_moveMemory( *ppStream, pStream, *pBytes ); 728*cdf0e10cSrcweir if( rContext.m_bDecrypt ) 729*cdf0e10cSrcweir { 730*cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rContext ); 731*cdf0e10cSrcweir pEData->decrypt( reinterpret_cast<const sal_uInt8*>(*ppStream), 732*cdf0e10cSrcweir *pBytes, 733*cdf0e10cSrcweir reinterpret_cast<sal_uInt8*>(*ppStream), 734*cdf0e10cSrcweir m_nNumber, 735*cdf0e10cSrcweir m_nGeneration 736*cdf0e10cSrcweir ); // decrypt inplace 737*cdf0e10cSrcweir } 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir else 740*cdf0e10cSrcweir *ppStream = NULL, *pBytes = 0; 741*cdf0e10cSrcweir return bIsDeflated; 742*cdf0e10cSrcweir } 743*cdf0e10cSrcweir 744*cdf0e10cSrcweir static void unzipToBuffer( const char* pBegin, unsigned int nLen, 745*cdf0e10cSrcweir sal_uInt8** pOutBuf, sal_uInt32* pOutLen ) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir z_stream aZStr; 748*cdf0e10cSrcweir aZStr.next_in = (Bytef*)pBegin; 749*cdf0e10cSrcweir aZStr.avail_in = nLen; 750*cdf0e10cSrcweir aZStr.zalloc = ( alloc_func )0; 751*cdf0e10cSrcweir aZStr.zfree = ( free_func )0; 752*cdf0e10cSrcweir aZStr.opaque = ( voidpf )0; 753*cdf0e10cSrcweir inflateInit(&aZStr); 754*cdf0e10cSrcweir 755*cdf0e10cSrcweir const unsigned int buf_increment_size = 16384; 756*cdf0e10cSrcweir 757*cdf0e10cSrcweir *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, buf_increment_size ); 758*cdf0e10cSrcweir aZStr.next_out = (Bytef*)*pOutBuf; 759*cdf0e10cSrcweir aZStr.avail_out = buf_increment_size; 760*cdf0e10cSrcweir int err = Z_OK; 761*cdf0e10cSrcweir *pOutLen = buf_increment_size; 762*cdf0e10cSrcweir while( err != Z_STREAM_END && err >= Z_OK && aZStr.avail_in ) 763*cdf0e10cSrcweir { 764*cdf0e10cSrcweir err = inflate( &aZStr, Z_NO_FLUSH ); 765*cdf0e10cSrcweir if( aZStr.avail_out == 0 ) 766*cdf0e10cSrcweir { 767*cdf0e10cSrcweir if( err != Z_STREAM_END ) 768*cdf0e10cSrcweir { 769*cdf0e10cSrcweir const int nNewAlloc = *pOutLen + buf_increment_size; 770*cdf0e10cSrcweir *pOutBuf = (sal_uInt8*)rtl_reallocateMemory( *pOutBuf, nNewAlloc ); 771*cdf0e10cSrcweir aZStr.next_out = (Bytef*)(*pOutBuf + *pOutLen); 772*cdf0e10cSrcweir aZStr.avail_out = buf_increment_size; 773*cdf0e10cSrcweir *pOutLen = nNewAlloc; 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir } 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir if( err == Z_STREAM_END ) 778*cdf0e10cSrcweir { 779*cdf0e10cSrcweir if( aZStr.avail_out > 0 ) 780*cdf0e10cSrcweir *pOutLen -= aZStr.avail_out;; 781*cdf0e10cSrcweir } 782*cdf0e10cSrcweir inflateEnd(&aZStr); 783*cdf0e10cSrcweir if( err < Z_OK ) 784*cdf0e10cSrcweir { 785*cdf0e10cSrcweir rtl_freeMemory( *pOutBuf ); 786*cdf0e10cSrcweir *pOutBuf = NULL; 787*cdf0e10cSrcweir *pOutLen = 0; 788*cdf0e10cSrcweir } 789*cdf0e10cSrcweir } 790*cdf0e10cSrcweir 791*cdf0e10cSrcweir bool PDFObject::writeStream( EmitContext& rWriteContext, const PDFFile* pParsedFile ) const 792*cdf0e10cSrcweir { 793*cdf0e10cSrcweir bool bSuccess = false; 794*cdf0e10cSrcweir if( m_pStream ) 795*cdf0e10cSrcweir { 796*cdf0e10cSrcweir char* pStream = NULL; 797*cdf0e10cSrcweir unsigned int nBytes = 0; 798*cdf0e10cSrcweir if( getDeflatedStream( &pStream, &nBytes, pParsedFile, rWriteContext ) && nBytes && rWriteContext.m_bDeflate ) 799*cdf0e10cSrcweir { 800*cdf0e10cSrcweir sal_uInt8* pOutBytes = NULL; 801*cdf0e10cSrcweir sal_uInt32 nOutBytes = 0; 802*cdf0e10cSrcweir unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes ); 803*cdf0e10cSrcweir rWriteContext.write( pOutBytes, nOutBytes ); 804*cdf0e10cSrcweir rtl_freeMemory( pOutBytes ); 805*cdf0e10cSrcweir } 806*cdf0e10cSrcweir else if( pStream && nBytes ) 807*cdf0e10cSrcweir rWriteContext.write( pStream, nBytes ); 808*cdf0e10cSrcweir rtl_freeMemory( pStream ); 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir return bSuccess; 811*cdf0e10cSrcweir } 812*cdf0e10cSrcweir 813*cdf0e10cSrcweir bool PDFObject::emit( EmitContext& rWriteContext ) const 814*cdf0e10cSrcweir { 815*cdf0e10cSrcweir if( ! rWriteContext.write( "\n", 1 ) ) 816*cdf0e10cSrcweir return false; 817*cdf0e10cSrcweir 818*cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext ); 819*cdf0e10cSrcweir if( pEData ) 820*cdf0e10cSrcweir pEData->insertXref( m_nNumber, m_nGeneration, rWriteContext.getCurPos() ); 821*cdf0e10cSrcweir 822*cdf0e10cSrcweir OStringBuffer aBuf( 32 ); 823*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nNumber ) ); 824*cdf0e10cSrcweir aBuf.append( ' ' ); 825*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nGeneration ) ); 826*cdf0e10cSrcweir aBuf.append( " obj\n" ); 827*cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) ) 828*cdf0e10cSrcweir return false; 829*cdf0e10cSrcweir 830*cdf0e10cSrcweir if( pEData ) 831*cdf0e10cSrcweir pEData->setDecryptObject( m_nNumber, m_nGeneration ); 832*cdf0e10cSrcweir if( (rWriteContext.m_bDeflate || rWriteContext.m_bDecrypt) && pEData ) 833*cdf0e10cSrcweir { 834*cdf0e10cSrcweir char* pStream = NULL; 835*cdf0e10cSrcweir unsigned int nBytes = 0; 836*cdf0e10cSrcweir bool bDeflate = getDeflatedStream( &pStream, &nBytes, pEData->m_pObjectContainer, rWriteContext ); 837*cdf0e10cSrcweir if( pStream && nBytes ) 838*cdf0e10cSrcweir { 839*cdf0e10cSrcweir // unzip the stream 840*cdf0e10cSrcweir sal_uInt8* pOutBytes = NULL; 841*cdf0e10cSrcweir sal_uInt32 nOutBytes = 0; 842*cdf0e10cSrcweir if( bDeflate && rWriteContext.m_bDeflate ) 843*cdf0e10cSrcweir unzipToBuffer( pStream, nBytes, &pOutBytes, &nOutBytes ); 844*cdf0e10cSrcweir else 845*cdf0e10cSrcweir { 846*cdf0e10cSrcweir // nothing to deflate, but decryption has happened 847*cdf0e10cSrcweir pOutBytes = (sal_uInt8*)pStream; 848*cdf0e10cSrcweir nOutBytes = (sal_uInt32)nBytes; 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir if( nOutBytes ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir // clone this object 854*cdf0e10cSrcweir PDFObject* pClone = static_cast<PDFObject*>(clone()); 855*cdf0e10cSrcweir // set length in the dictionary to new stream length 856*cdf0e10cSrcweir PDFNumber* pNewLen = new PDFNumber( double(nOutBytes) ); 857*cdf0e10cSrcweir pClone->m_pStream->m_pDict->insertValue( "Length", pNewLen ); 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir if( bDeflate && rWriteContext.m_bDeflate ) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir // delete flatedecode filter 862*cdf0e10cSrcweir std::hash_map<OString,PDFEntry*,OStringHash>::const_iterator it = 863*cdf0e10cSrcweir pClone->m_pStream->m_pDict->m_aMap.find( "Filter" ); 864*cdf0e10cSrcweir if( it != pClone->m_pStream->m_pDict->m_aMap.end() ) 865*cdf0e10cSrcweir { 866*cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(it->second); 867*cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) ) 868*cdf0e10cSrcweir pClone->m_pStream->m_pDict->eraseValue( "Filter" ); 869*cdf0e10cSrcweir else 870*cdf0e10cSrcweir { 871*cdf0e10cSrcweir PDFArray* pArray = dynamic_cast<PDFArray*>(it->second); 872*cdf0e10cSrcweir if( pArray && ! pArray->m_aSubElements.empty() ) 873*cdf0e10cSrcweir { 874*cdf0e10cSrcweir pFilter = dynamic_cast<PDFName*>(pArray->m_aSubElements.front()); 875*cdf0e10cSrcweir if( pFilter && pFilter->m_aName.equals( "FlateDecode" ) ) 876*cdf0e10cSrcweir { 877*cdf0e10cSrcweir delete pFilter; 878*cdf0e10cSrcweir pArray->m_aSubElements.erase( pArray->m_aSubElements.begin() ); 879*cdf0e10cSrcweir } 880*cdf0e10cSrcweir } 881*cdf0e10cSrcweir } 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir // write sub elements except stream 886*cdf0e10cSrcweir bool bRet = true; 887*cdf0e10cSrcweir unsigned int nEle = pClone->m_aSubElements.size(); 888*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle && bRet; i++ ) 889*cdf0e10cSrcweir { 890*cdf0e10cSrcweir if( pClone->m_aSubElements[i] != pClone->m_pStream ) 891*cdf0e10cSrcweir bRet = pClone->m_aSubElements[i]->emit( rWriteContext ); 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir delete pClone; 894*cdf0e10cSrcweir // write stream 895*cdf0e10cSrcweir if( bRet ) 896*cdf0e10cSrcweir rWriteContext.write( "stream\n", 7 ); 897*cdf0e10cSrcweir if( bRet ) 898*cdf0e10cSrcweir bRet = rWriteContext.write( pOutBytes, nOutBytes ); 899*cdf0e10cSrcweir if( bRet ) 900*cdf0e10cSrcweir bRet = rWriteContext.write( "\nendstream\nendobj\n", 18 ); 901*cdf0e10cSrcweir rtl_freeMemory( pStream ); 902*cdf0e10cSrcweir if( pOutBytes != (sal_uInt8*)pStream ) 903*cdf0e10cSrcweir rtl_freeMemory( pOutBytes ); 904*cdf0e10cSrcweir if( pEData ) 905*cdf0e10cSrcweir pEData->setDecryptObject( 0, 0 ); 906*cdf0e10cSrcweir return bRet; 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir if( pOutBytes != (sal_uInt8*)pStream ) 909*cdf0e10cSrcweir rtl_freeMemory( pOutBytes ); 910*cdf0e10cSrcweir } 911*cdf0e10cSrcweir rtl_freeMemory( pStream ); 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir 914*cdf0e10cSrcweir bool bRet = emitSubElements( rWriteContext ) && 915*cdf0e10cSrcweir rWriteContext.write( "\nendobj\n", 8 ); 916*cdf0e10cSrcweir if( pEData ) 917*cdf0e10cSrcweir pEData->setDecryptObject( 0, 0 ); 918*cdf0e10cSrcweir return bRet; 919*cdf0e10cSrcweir } 920*cdf0e10cSrcweir 921*cdf0e10cSrcweir PDFEntry* PDFObject::clone() const 922*cdf0e10cSrcweir { 923*cdf0e10cSrcweir PDFObject* pNewOb = new PDFObject( m_nNumber, m_nGeneration ); 924*cdf0e10cSrcweir cloneSubElements( pNewOb->m_aSubElements ); 925*cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size(); 926*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ ) 927*cdf0e10cSrcweir { 928*cdf0e10cSrcweir if( m_aSubElements[i] == m_pObject ) 929*cdf0e10cSrcweir pNewOb->m_pObject = pNewOb->m_aSubElements[i]; 930*cdf0e10cSrcweir else if( m_aSubElements[i] == m_pStream && pNewOb->m_pObject ) 931*cdf0e10cSrcweir { 932*cdf0e10cSrcweir pNewOb->m_pStream = dynamic_cast<PDFStream*>(pNewOb->m_aSubElements[i]); 933*cdf0e10cSrcweir PDFDict* pNewDict = dynamic_cast<PDFDict*>(pNewOb->m_pObject); 934*cdf0e10cSrcweir if( pNewDict ) 935*cdf0e10cSrcweir pNewOb->m_pStream->m_pDict = pNewDict; 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir return pNewOb; 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir PDFTrailer::~PDFTrailer() 942*cdf0e10cSrcweir { 943*cdf0e10cSrcweir } 944*cdf0e10cSrcweir 945*cdf0e10cSrcweir bool PDFTrailer::emit( EmitContext& rWriteContext ) const 946*cdf0e10cSrcweir { 947*cdf0e10cSrcweir // get xref offset 948*cdf0e10cSrcweir unsigned int nXRefPos = rWriteContext.getCurPos(); 949*cdf0e10cSrcweir // begin xref section, object 0 is always free 950*cdf0e10cSrcweir if( ! rWriteContext.write( "xref\r\n" 951*cdf0e10cSrcweir "0 1\r\n" 952*cdf0e10cSrcweir "0000000000 65535 f\r\n", 31 ) ) 953*cdf0e10cSrcweir return false; 954*cdf0e10cSrcweir // check if we are emitting a complete PDF file 955*cdf0e10cSrcweir EmitImplData* pEData = getEmitData( rWriteContext ); 956*cdf0e10cSrcweir if( pEData ) 957*cdf0e10cSrcweir { 958*cdf0e10cSrcweir // emit object xrefs 959*cdf0e10cSrcweir const EmitImplData::XRefTable& rXRefs = pEData->m_aXRefTable; 960*cdf0e10cSrcweir EmitImplData::XRefTable::const_iterator section_begin, section_end; 961*cdf0e10cSrcweir section_begin = rXRefs.begin(); 962*cdf0e10cSrcweir while( section_begin != rXRefs.end() ) 963*cdf0e10cSrcweir { 964*cdf0e10cSrcweir // find end of continuous object numbers 965*cdf0e10cSrcweir section_end = section_begin; 966*cdf0e10cSrcweir unsigned int nLast = section_begin->first; 967*cdf0e10cSrcweir while( (++section_end) != rXRefs.end() && 968*cdf0e10cSrcweir section_end->first == nLast+1 ) 969*cdf0e10cSrcweir nLast = section_end->first; 970*cdf0e10cSrcweir // write first object number and number of following entries 971*cdf0e10cSrcweir OStringBuffer aBuf( 21 ); 972*cdf0e10cSrcweir aBuf.append( sal_Int32( section_begin->first ) ); 973*cdf0e10cSrcweir aBuf.append( ' ' ); 974*cdf0e10cSrcweir aBuf.append( sal_Int32(nLast - section_begin->first + 1) ); 975*cdf0e10cSrcweir aBuf.append( "\r\n" ); 976*cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) ) 977*cdf0e10cSrcweir return false; 978*cdf0e10cSrcweir while( section_begin != section_end ) 979*cdf0e10cSrcweir { 980*cdf0e10cSrcweir // write 20 char entry of form 981*cdf0e10cSrcweir // 0000offset 00gen n\r\n 982*cdf0e10cSrcweir aBuf.setLength( 0 ); 983*cdf0e10cSrcweir OString aOffset( OString::valueOf( sal_Int64(section_begin->second.second ) ) ); 984*cdf0e10cSrcweir int nPad = 10 - aOffset.getLength(); 985*cdf0e10cSrcweir for( int i = 0; i < nPad; i++ ) 986*cdf0e10cSrcweir aBuf.append( '0' ); 987*cdf0e10cSrcweir aBuf.append( aOffset ); 988*cdf0e10cSrcweir aBuf.append( ' ' ); 989*cdf0e10cSrcweir OString aGeneration( OString::valueOf( sal_Int32(section_begin->second.first ) ) ); 990*cdf0e10cSrcweir nPad = 5 - aGeneration.getLength(); 991*cdf0e10cSrcweir for( int i = 0; i < nPad; i++ ) 992*cdf0e10cSrcweir aBuf.append( '0' ); 993*cdf0e10cSrcweir aBuf.append( aGeneration ); 994*cdf0e10cSrcweir aBuf.append( " n\r\n" ); 995*cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), 20 ) ) 996*cdf0e10cSrcweir return false; 997*cdf0e10cSrcweir ++section_begin; 998*cdf0e10cSrcweir } 999*cdf0e10cSrcweir } 1000*cdf0e10cSrcweir } 1001*cdf0e10cSrcweir if( ! rWriteContext.write( "trailer\n", 8 ) ) 1002*cdf0e10cSrcweir return false; 1003*cdf0e10cSrcweir if( ! emitSubElements( rWriteContext ) ) 1004*cdf0e10cSrcweir return false; 1005*cdf0e10cSrcweir if( ! rWriteContext.write( "startxref\n", 10 ) ) 1006*cdf0e10cSrcweir return false; 1007*cdf0e10cSrcweir rtl::OString aOffset( rtl::OString::valueOf( sal_Int32(nXRefPos) ) ); 1008*cdf0e10cSrcweir if( ! rWriteContext.write( aOffset.getStr(), aOffset.getLength() ) ) 1009*cdf0e10cSrcweir return false; 1010*cdf0e10cSrcweir return rWriteContext.write( "\n%%EOF\n", 7 ); 1011*cdf0e10cSrcweir } 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir PDFEntry* PDFTrailer::clone() const 1014*cdf0e10cSrcweir { 1015*cdf0e10cSrcweir PDFTrailer* pNewTr = new PDFTrailer(); 1016*cdf0e10cSrcweir cloneSubElements( pNewTr->m_aSubElements ); 1017*cdf0e10cSrcweir unsigned int nEle = m_aSubElements.size(); 1018*cdf0e10cSrcweir for( unsigned int i = 0; i < nEle; i++ ) 1019*cdf0e10cSrcweir { 1020*cdf0e10cSrcweir if( m_aSubElements[i] == m_pDict ) 1021*cdf0e10cSrcweir { 1022*cdf0e10cSrcweir pNewTr->m_pDict = dynamic_cast<PDFDict*>(pNewTr->m_aSubElements[i]); 1023*cdf0e10cSrcweir break; 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir } 1026*cdf0e10cSrcweir return pNewTr; 1027*cdf0e10cSrcweir } 1028*cdf0e10cSrcweir 1029*cdf0e10cSrcweir #define ENCRYPTION_KEY_LEN 16 1030*cdf0e10cSrcweir #define ENCRYPTION_BUF_LEN 32 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir namespace pdfparse { 1033*cdf0e10cSrcweir struct PDFFileImplData 1034*cdf0e10cSrcweir { 1035*cdf0e10cSrcweir bool m_bIsEncrypted; 1036*cdf0e10cSrcweir bool m_bStandardHandler; 1037*cdf0e10cSrcweir sal_uInt32 m_nAlgoVersion; 1038*cdf0e10cSrcweir sal_uInt32 m_nStandardRevision; 1039*cdf0e10cSrcweir sal_uInt32 m_nKeyLength; 1040*cdf0e10cSrcweir sal_uInt8 m_aOEntry[32]; 1041*cdf0e10cSrcweir sal_uInt8 m_aUEntry[32]; 1042*cdf0e10cSrcweir sal_uInt32 m_nPEntry; 1043*cdf0e10cSrcweir OString m_aDocID; 1044*cdf0e10cSrcweir rtlCipher m_aCipher; 1045*cdf0e10cSrcweir rtlDigest m_aDigest; 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir sal_uInt8 m_aDecryptionKey[ENCRYPTION_KEY_LEN+5]; // maximum handled key length 1048*cdf0e10cSrcweir 1049*cdf0e10cSrcweir PDFFileImplData() : 1050*cdf0e10cSrcweir m_bIsEncrypted( false ), 1051*cdf0e10cSrcweir m_bStandardHandler( false ), 1052*cdf0e10cSrcweir m_nAlgoVersion( 0 ), 1053*cdf0e10cSrcweir m_nStandardRevision( 0 ), 1054*cdf0e10cSrcweir m_nKeyLength( 0 ), 1055*cdf0e10cSrcweir m_nPEntry( 0 ), 1056*cdf0e10cSrcweir m_aCipher( NULL ), 1057*cdf0e10cSrcweir m_aDigest( NULL ) 1058*cdf0e10cSrcweir { 1059*cdf0e10cSrcweir rtl_zeroMemory( m_aOEntry, sizeof( m_aOEntry ) ); 1060*cdf0e10cSrcweir rtl_zeroMemory( m_aUEntry, sizeof( m_aUEntry ) ); 1061*cdf0e10cSrcweir rtl_zeroMemory( m_aDecryptionKey, sizeof( m_aDecryptionKey ) ); 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir 1064*cdf0e10cSrcweir ~PDFFileImplData() 1065*cdf0e10cSrcweir { 1066*cdf0e10cSrcweir if( m_aCipher ) 1067*cdf0e10cSrcweir rtl_cipher_destroyARCFOUR( m_aCipher ); 1068*cdf0e10cSrcweir if( m_aDigest ) 1069*cdf0e10cSrcweir rtl_digest_destroyMD5( m_aDigest ); 1070*cdf0e10cSrcweir } 1071*cdf0e10cSrcweir }; 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir 1074*cdf0e10cSrcweir PDFFile::~PDFFile() 1075*cdf0e10cSrcweir { 1076*cdf0e10cSrcweir if( m_pData ) 1077*cdf0e10cSrcweir delete m_pData; 1078*cdf0e10cSrcweir } 1079*cdf0e10cSrcweir 1080*cdf0e10cSrcweir bool PDFFile::isEncrypted() const 1081*cdf0e10cSrcweir { 1082*cdf0e10cSrcweir return impl_getData()->m_bIsEncrypted; 1083*cdf0e10cSrcweir } 1084*cdf0e10cSrcweir 1085*cdf0e10cSrcweir bool PDFFile::decrypt( const sal_uInt8* pInBuffer, sal_uInt32 nLen, sal_uInt8* pOutBuffer, 1086*cdf0e10cSrcweir unsigned int nObject, unsigned int nGeneration ) const 1087*cdf0e10cSrcweir { 1088*cdf0e10cSrcweir if( ! isEncrypted() ) 1089*cdf0e10cSrcweir return false; 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir if( ! m_pData->m_aCipher ) 1092*cdf0e10cSrcweir m_pData->m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream ); 1093*cdf0e10cSrcweir 1094*cdf0e10cSrcweir // modify encryption key 1095*cdf0e10cSrcweir sal_uInt32 i = m_pData->m_nKeyLength; 1096*cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8(nObject&0xff); 1097*cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>8)&0xff); 1098*cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nObject>>16)&0xff); 1099*cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8(nGeneration&0xff); 1100*cdf0e10cSrcweir m_pData->m_aDecryptionKey[i++] = sal_uInt8((nGeneration>>8)&0xff); 1101*cdf0e10cSrcweir 1102*cdf0e10cSrcweir sal_uInt8 aSum[ENCRYPTION_KEY_LEN]; 1103*cdf0e10cSrcweir rtl_digest_updateMD5( m_pData->m_aDigest, m_pData->m_aDecryptionKey, i ); 1104*cdf0e10cSrcweir rtl_digest_getMD5( m_pData->m_aDigest, aSum, sizeof( aSum ) ); 1105*cdf0e10cSrcweir 1106*cdf0e10cSrcweir if( i > 16 ) 1107*cdf0e10cSrcweir i = 16; 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir rtlCipherError aErr = rtl_cipher_initARCFOUR( m_pData->m_aCipher, 1110*cdf0e10cSrcweir rtl_Cipher_DirectionDecode, 1111*cdf0e10cSrcweir aSum, i, 1112*cdf0e10cSrcweir NULL, 0 ); 1113*cdf0e10cSrcweir if( aErr == rtl_Cipher_E_None ) 1114*cdf0e10cSrcweir aErr = rtl_cipher_decodeARCFOUR( m_pData->m_aCipher, 1115*cdf0e10cSrcweir pInBuffer, nLen, 1116*cdf0e10cSrcweir pOutBuffer, nLen ); 1117*cdf0e10cSrcweir return aErr == rtl_Cipher_E_None; 1118*cdf0e10cSrcweir } 1119*cdf0e10cSrcweir 1120*cdf0e10cSrcweir static const sal_uInt8 nPadString[32] = 1121*cdf0e10cSrcweir { 1122*cdf0e10cSrcweir 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08, 1123*cdf0e10cSrcweir 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A 1124*cdf0e10cSrcweir }; 1125*cdf0e10cSrcweir 1126*cdf0e10cSrcweir static void pad_or_truncate_to_32( const OString& rStr, sal_Char* pBuffer ) 1127*cdf0e10cSrcweir { 1128*cdf0e10cSrcweir int nLen = rStr.getLength(); 1129*cdf0e10cSrcweir if( nLen > 32 ) 1130*cdf0e10cSrcweir nLen = 32; 1131*cdf0e10cSrcweir const sal_Char* pStr = rStr.getStr(); 1132*cdf0e10cSrcweir rtl_copyMemory( pBuffer, pStr, nLen ); 1133*cdf0e10cSrcweir int i = 0; 1134*cdf0e10cSrcweir while( nLen < 32 ) 1135*cdf0e10cSrcweir pBuffer[nLen++] = nPadString[i++]; 1136*cdf0e10cSrcweir } 1137*cdf0e10cSrcweir 1138*cdf0e10cSrcweir // pass at least pData->m_nKeyLength bytes in 1139*cdf0e10cSrcweir static sal_uInt32 password_to_key( const OString& rPwd, sal_uInt8* pOutKey, PDFFileImplData* pData, bool bComputeO ) 1140*cdf0e10cSrcweir { 1141*cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.2 1142*cdf0e10cSrcweir // encrypt pad string 1143*cdf0e10cSrcweir sal_Char aPadPwd[ENCRYPTION_BUF_LEN]; 1144*cdf0e10cSrcweir pad_or_truncate_to_32( rPwd, aPadPwd ); 1145*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, aPadPwd, sizeof( aPadPwd ) ); 1146*cdf0e10cSrcweir if( ! bComputeO ) 1147*cdf0e10cSrcweir { 1148*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aOEntry, 32 ); 1149*cdf0e10cSrcweir sal_uInt8 aPEntry[4]; 1150*cdf0e10cSrcweir aPEntry[0] = static_cast<sal_uInt8>(pData->m_nPEntry & 0xff); 1151*cdf0e10cSrcweir aPEntry[1] = static_cast<sal_uInt8>((pData->m_nPEntry >> 8 ) & 0xff); 1152*cdf0e10cSrcweir aPEntry[2] = static_cast<sal_uInt8>((pData->m_nPEntry >> 16) & 0xff); 1153*cdf0e10cSrcweir aPEntry[3] = static_cast<sal_uInt8>((pData->m_nPEntry >> 24) & 0xff); 1154*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, aPEntry, sizeof(aPEntry) ); 1155*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() ); 1156*cdf0e10cSrcweir } 1157*cdf0e10cSrcweir sal_uInt8 nSum[RTL_DIGEST_LENGTH_MD5]; 1158*cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) ); 1159*cdf0e10cSrcweir if( pData->m_nStandardRevision == 3 ) 1160*cdf0e10cSrcweir { 1161*cdf0e10cSrcweir for( int i = 0; i < 50; i++ ) 1162*cdf0e10cSrcweir { 1163*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, nSum, sizeof(nSum) ); 1164*cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nSum, sizeof(nSum) ); 1165*cdf0e10cSrcweir } 1166*cdf0e10cSrcweir } 1167*cdf0e10cSrcweir sal_uInt32 nLen = pData->m_nKeyLength; 1168*cdf0e10cSrcweir if( nLen > RTL_DIGEST_LENGTH_MD5 ) 1169*cdf0e10cSrcweir nLen = RTL_DIGEST_LENGTH_MD5; 1170*cdf0e10cSrcweir rtl_copyMemory( pOutKey, nSum, nLen ); 1171*cdf0e10cSrcweir return nLen; 1172*cdf0e10cSrcweir } 1173*cdf0e10cSrcweir 1174*cdf0e10cSrcweir static bool check_user_password( const OString& rPwd, PDFFileImplData* pData ) 1175*cdf0e10cSrcweir { 1176*cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.6 1177*cdf0e10cSrcweir bool bValid = false; 1178*cdf0e10cSrcweir sal_uInt8 aKey[ENCRYPTION_KEY_LEN]; 1179*cdf0e10cSrcweir sal_uInt8 nEncryptedEntry[ENCRYPTION_BUF_LEN]; 1180*cdf0e10cSrcweir rtl_zeroMemory( nEncryptedEntry, sizeof(nEncryptedEntry) ); 1181*cdf0e10cSrcweir sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, pData, false ); 1182*cdf0e10cSrcweir // save (at this time potential) decryption key for later use 1183*cdf0e10cSrcweir rtl_copyMemory( pData->m_aDecryptionKey, aKey, nKeyLen ); 1184*cdf0e10cSrcweir if( pData->m_nStandardRevision == 2 ) 1185*cdf0e10cSrcweir { 1186*cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.4 1187*cdf0e10cSrcweir // encrypt pad string 1188*cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 1189*cdf0e10cSrcweir aKey, nKeyLen, 1190*cdf0e10cSrcweir NULL, 0 ); 1191*cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher, nPadString, sizeof( nPadString ), 1192*cdf0e10cSrcweir nEncryptedEntry, sizeof( nEncryptedEntry ) ); 1193*cdf0e10cSrcweir bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 32 ) == 0); 1194*cdf0e10cSrcweir } 1195*cdf0e10cSrcweir else if( pData->m_nStandardRevision == 3 ) 1196*cdf0e10cSrcweir { 1197*cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.5 1198*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, nPadString, sizeof( nPadString ) ); 1199*cdf0e10cSrcweir rtl_digest_updateMD5( pData->m_aDigest, pData->m_aDocID.getStr(), pData->m_aDocID.getLength() ); 1200*cdf0e10cSrcweir rtl_digest_getMD5( pData->m_aDigest, nEncryptedEntry, sizeof(nEncryptedEntry) ); 1201*cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 1202*cdf0e10cSrcweir aKey, sizeof(aKey), NULL, 0 ); 1203*cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher, 1204*cdf0e10cSrcweir nEncryptedEntry, 16, 1205*cdf0e10cSrcweir nEncryptedEntry, 16 ); // encrypt in place 1206*cdf0e10cSrcweir for( int i = 1; i <= 19; i++ ) // do it 19 times, start with 1 1207*cdf0e10cSrcweir { 1208*cdf0e10cSrcweir sal_uInt8 aTempKey[ENCRYPTION_KEY_LEN]; 1209*cdf0e10cSrcweir for( sal_uInt32 j = 0; j < sizeof(aTempKey); j++ ) 1210*cdf0e10cSrcweir aTempKey[j] = static_cast<sal_uInt8>( aKey[j] ^ i ); 1211*cdf0e10cSrcweir 1212*cdf0e10cSrcweir rtl_cipher_initARCFOUR( pData->m_aCipher, rtl_Cipher_DirectionEncode, 1213*cdf0e10cSrcweir aTempKey, sizeof(aTempKey), NULL, 0 ); 1214*cdf0e10cSrcweir rtl_cipher_encodeARCFOUR( pData->m_aCipher, 1215*cdf0e10cSrcweir nEncryptedEntry, 16, 1216*cdf0e10cSrcweir nEncryptedEntry, 16 ); // encrypt in place 1217*cdf0e10cSrcweir } 1218*cdf0e10cSrcweir bValid = (rtl_compareMemory( nEncryptedEntry, pData->m_aUEntry, 16 ) == 0); 1219*cdf0e10cSrcweir } 1220*cdf0e10cSrcweir return bValid; 1221*cdf0e10cSrcweir } 1222*cdf0e10cSrcweir 1223*cdf0e10cSrcweir bool PDFFile::setupDecryptionData( const OString& rPwd ) const 1224*cdf0e10cSrcweir { 1225*cdf0e10cSrcweir if( !impl_getData()->m_bIsEncrypted ) 1226*cdf0e10cSrcweir return rPwd.getLength() == 0; 1227*cdf0e10cSrcweir 1228*cdf0e10cSrcweir // check if we can handle this encryption at all 1229*cdf0e10cSrcweir if( ! m_pData->m_bStandardHandler || 1230*cdf0e10cSrcweir m_pData->m_nAlgoVersion < 1 || 1231*cdf0e10cSrcweir m_pData->m_nAlgoVersion > 2 || 1232*cdf0e10cSrcweir m_pData->m_nStandardRevision < 2 || 1233*cdf0e10cSrcweir m_pData->m_nStandardRevision > 3 ) 1234*cdf0e10cSrcweir return false; 1235*cdf0e10cSrcweir 1236*cdf0e10cSrcweir if( ! m_pData->m_aCipher ) 1237*cdf0e10cSrcweir m_pData->m_aCipher = rtl_cipher_createARCFOUR(rtl_Cipher_ModeStream); 1238*cdf0e10cSrcweir if( ! m_pData->m_aDigest ) 1239*cdf0e10cSrcweir m_pData->m_aDigest = rtl_digest_createMD5(); 1240*cdf0e10cSrcweir 1241*cdf0e10cSrcweir // first try user password 1242*cdf0e10cSrcweir bool bValid = check_user_password( rPwd, m_pData ); 1243*cdf0e10cSrcweir 1244*cdf0e10cSrcweir if( ! bValid ) 1245*cdf0e10cSrcweir { 1246*cdf0e10cSrcweir // try owner password 1247*cdf0e10cSrcweir // see PDF reference 1.4 Algorithm 3.7 1248*cdf0e10cSrcweir sal_uInt8 aKey[ENCRYPTION_KEY_LEN]; 1249*cdf0e10cSrcweir sal_uInt8 nPwd[ENCRYPTION_BUF_LEN]; 1250*cdf0e10cSrcweir rtl_zeroMemory( nPwd, sizeof(nPwd) ); 1251*cdf0e10cSrcweir sal_uInt32 nKeyLen = password_to_key( rPwd, aKey, m_pData, true ); 1252*cdf0e10cSrcweir if( m_pData->m_nStandardRevision == 2 ) 1253*cdf0e10cSrcweir { 1254*cdf0e10cSrcweir rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode, 1255*cdf0e10cSrcweir aKey, nKeyLen, NULL, 0 ); 1256*cdf0e10cSrcweir rtl_cipher_decodeARCFOUR( m_pData->m_aCipher, 1257*cdf0e10cSrcweir m_pData->m_aOEntry, 32, 1258*cdf0e10cSrcweir nPwd, 32 ); 1259*cdf0e10cSrcweir } 1260*cdf0e10cSrcweir else if( m_pData->m_nStandardRevision == 3 ) 1261*cdf0e10cSrcweir { 1262*cdf0e10cSrcweir rtl_copyMemory( nPwd, m_pData->m_aOEntry, 32 ); 1263*cdf0e10cSrcweir for( int i = 19; i >= 0; i-- ) 1264*cdf0e10cSrcweir { 1265*cdf0e10cSrcweir sal_uInt8 nTempKey[ENCRYPTION_KEY_LEN]; 1266*cdf0e10cSrcweir for( unsigned int j = 0; j < sizeof(nTempKey); j++ ) 1267*cdf0e10cSrcweir nTempKey[j] = sal_uInt8(aKey[j] ^ i); 1268*cdf0e10cSrcweir rtl_cipher_initARCFOUR( m_pData->m_aCipher, rtl_Cipher_DirectionDecode, 1269*cdf0e10cSrcweir nTempKey, nKeyLen, NULL, 0 ); 1270*cdf0e10cSrcweir rtl_cipher_decodeARCFOUR( m_pData->m_aCipher, 1271*cdf0e10cSrcweir nPwd, 32, 1272*cdf0e10cSrcweir nPwd, 32 ); // decrypt inplace 1273*cdf0e10cSrcweir } 1274*cdf0e10cSrcweir } 1275*cdf0e10cSrcweir bValid = check_user_password( OString( (sal_Char*)nPwd, 32 ), m_pData ); 1276*cdf0e10cSrcweir } 1277*cdf0e10cSrcweir 1278*cdf0e10cSrcweir return bValid; 1279*cdf0e10cSrcweir } 1280*cdf0e10cSrcweir 1281*cdf0e10cSrcweir rtl::OUString PDFFile::getDecryptionKey() const 1282*cdf0e10cSrcweir { 1283*cdf0e10cSrcweir rtl::OUStringBuffer aBuf( ENCRYPTION_KEY_LEN * 2 ); 1284*cdf0e10cSrcweir if( impl_getData()->m_bIsEncrypted ) 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir for( sal_uInt32 i = 0; i < m_pData->m_nKeyLength; i++ ) 1287*cdf0e10cSrcweir { 1288*cdf0e10cSrcweir static const sal_Unicode pHexTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7', 1289*cdf0e10cSrcweir '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 1290*cdf0e10cSrcweir aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] >> 4) & 0x0f] ); 1291*cdf0e10cSrcweir aBuf.append( pHexTab[(m_pData->m_aDecryptionKey[i] & 0x0f)] ); 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir 1294*cdf0e10cSrcweir } 1295*cdf0e10cSrcweir return aBuf.makeStringAndClear(); 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir 1298*cdf0e10cSrcweir PDFFileImplData* PDFFile::impl_getData() const 1299*cdf0e10cSrcweir { 1300*cdf0e10cSrcweir if( m_pData ) 1301*cdf0e10cSrcweir return m_pData; 1302*cdf0e10cSrcweir m_pData = new PDFFileImplData(); 1303*cdf0e10cSrcweir // check for encryption dict in a trailer 1304*cdf0e10cSrcweir unsigned int nElements = m_aSubElements.size(); 1305*cdf0e10cSrcweir while( nElements-- > 0 ) 1306*cdf0e10cSrcweir { 1307*cdf0e10cSrcweir PDFTrailer* pTrailer = dynamic_cast<PDFTrailer*>(m_aSubElements[nElements]); 1308*cdf0e10cSrcweir if( pTrailer && pTrailer->m_pDict ) 1309*cdf0e10cSrcweir { 1310*cdf0e10cSrcweir // search doc id 1311*cdf0e10cSrcweir PDFDict::Map::iterator doc_id = pTrailer->m_pDict->m_aMap.find( "ID" ); 1312*cdf0e10cSrcweir if( doc_id != pTrailer->m_pDict->m_aMap.end() ) 1313*cdf0e10cSrcweir { 1314*cdf0e10cSrcweir PDFArray* pArr = dynamic_cast<PDFArray*>(doc_id->second); 1315*cdf0e10cSrcweir if( pArr && pArr->m_aSubElements.size() > 0 ) 1316*cdf0e10cSrcweir { 1317*cdf0e10cSrcweir PDFString* pStr = dynamic_cast<PDFString*>(pArr->m_aSubElements[0]); 1318*cdf0e10cSrcweir if( pStr ) 1319*cdf0e10cSrcweir m_pData->m_aDocID = pStr->getFilteredString(); 1320*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1321*cdf0e10cSrcweir fprintf( stderr, "DocId is <" ); 1322*cdf0e10cSrcweir for( int i = 0; i < m_pData->m_aDocID.getLength(); i++ ) 1323*cdf0e10cSrcweir fprintf( stderr, "%.2x", (unsigned int)sal_uInt8(m_pData->m_aDocID.getStr()[i]) ); 1324*cdf0e10cSrcweir fprintf( stderr, ">\n" ); 1325*cdf0e10cSrcweir #endif 1326*cdf0e10cSrcweir } 1327*cdf0e10cSrcweir } 1328*cdf0e10cSrcweir // search Encrypt entry 1329*cdf0e10cSrcweir PDFDict::Map::iterator enc = 1330*cdf0e10cSrcweir pTrailer->m_pDict->m_aMap.find( "Encrypt" ); 1331*cdf0e10cSrcweir if( enc != pTrailer->m_pDict->m_aMap.end() ) 1332*cdf0e10cSrcweir { 1333*cdf0e10cSrcweir PDFDict* pDict = dynamic_cast<PDFDict*>(enc->second); 1334*cdf0e10cSrcweir if( ! pDict ) 1335*cdf0e10cSrcweir { 1336*cdf0e10cSrcweir PDFObjectRef* pRef = dynamic_cast<PDFObjectRef*>(enc->second); 1337*cdf0e10cSrcweir if( pRef ) 1338*cdf0e10cSrcweir { 1339*cdf0e10cSrcweir PDFObject* pObj = findObject( pRef ); 1340*cdf0e10cSrcweir if( pObj && pObj->m_pObject ) 1341*cdf0e10cSrcweir pDict = dynamic_cast<PDFDict*>(pObj->m_pObject); 1342*cdf0e10cSrcweir } 1343*cdf0e10cSrcweir } 1344*cdf0e10cSrcweir if( pDict ) 1345*cdf0e10cSrcweir { 1346*cdf0e10cSrcweir PDFDict::Map::iterator filter = pDict->m_aMap.find( "Filter" ); 1347*cdf0e10cSrcweir PDFDict::Map::iterator version = pDict->m_aMap.find( "V" ); 1348*cdf0e10cSrcweir PDFDict::Map::iterator len = pDict->m_aMap.find( "Length" ); 1349*cdf0e10cSrcweir PDFDict::Map::iterator o_ent = pDict->m_aMap.find( "O" ); 1350*cdf0e10cSrcweir PDFDict::Map::iterator u_ent = pDict->m_aMap.find( "U" ); 1351*cdf0e10cSrcweir PDFDict::Map::iterator r_ent = pDict->m_aMap.find( "R" ); 1352*cdf0e10cSrcweir PDFDict::Map::iterator p_ent = pDict->m_aMap.find( "P" ); 1353*cdf0e10cSrcweir if( filter != pDict->m_aMap.end() ) 1354*cdf0e10cSrcweir { 1355*cdf0e10cSrcweir m_pData->m_bIsEncrypted = true; 1356*cdf0e10cSrcweir m_pData->m_nKeyLength = 5; 1357*cdf0e10cSrcweir if( version != pDict->m_aMap.end() ) 1358*cdf0e10cSrcweir { 1359*cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(version->second); 1360*cdf0e10cSrcweir if( pNum ) 1361*cdf0e10cSrcweir m_pData->m_nAlgoVersion = static_cast<sal_uInt32>(pNum->m_fValue); 1362*cdf0e10cSrcweir } 1363*cdf0e10cSrcweir if( m_pData->m_nAlgoVersion >= 3 ) 1364*cdf0e10cSrcweir m_pData->m_nKeyLength = 16; 1365*cdf0e10cSrcweir if( len != pDict->m_aMap.end() ) 1366*cdf0e10cSrcweir { 1367*cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(len->second); 1368*cdf0e10cSrcweir if( pNum ) 1369*cdf0e10cSrcweir m_pData->m_nKeyLength = static_cast<sal_uInt32>(pNum->m_fValue) / 8; 1370*cdf0e10cSrcweir } 1371*cdf0e10cSrcweir PDFName* pFilter = dynamic_cast<PDFName*>(filter->second); 1372*cdf0e10cSrcweir if( pFilter && pFilter->getFilteredName().equalsAscii( "Standard" ) ) 1373*cdf0e10cSrcweir m_pData->m_bStandardHandler = true; 1374*cdf0e10cSrcweir if( o_ent != pDict->m_aMap.end() ) 1375*cdf0e10cSrcweir { 1376*cdf0e10cSrcweir PDFString* pString = dynamic_cast<PDFString*>(o_ent->second); 1377*cdf0e10cSrcweir if( pString ) 1378*cdf0e10cSrcweir { 1379*cdf0e10cSrcweir OString aEnt = pString->getFilteredString(); 1380*cdf0e10cSrcweir if( aEnt.getLength() == 32 ) 1381*cdf0e10cSrcweir rtl_copyMemory( m_pData->m_aOEntry, aEnt.getStr(), 32 ); 1382*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1383*cdf0e10cSrcweir else 1384*cdf0e10cSrcweir { 1385*cdf0e10cSrcweir fprintf( stderr, "O entry has length %d, should be 32 <", (int)aEnt.getLength() ); 1386*cdf0e10cSrcweir for( int i = 0; i < aEnt.getLength(); i++ ) 1387*cdf0e10cSrcweir fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) ); 1388*cdf0e10cSrcweir fprintf( stderr, ">\n" ); 1389*cdf0e10cSrcweir } 1390*cdf0e10cSrcweir #endif 1391*cdf0e10cSrcweir } 1392*cdf0e10cSrcweir } 1393*cdf0e10cSrcweir if( u_ent != pDict->m_aMap.end() ) 1394*cdf0e10cSrcweir { 1395*cdf0e10cSrcweir PDFString* pString = dynamic_cast<PDFString*>(u_ent->second); 1396*cdf0e10cSrcweir if( pString ) 1397*cdf0e10cSrcweir { 1398*cdf0e10cSrcweir OString aEnt = pString->getFilteredString(); 1399*cdf0e10cSrcweir if( aEnt.getLength() == 32 ) 1400*cdf0e10cSrcweir rtl_copyMemory( m_pData->m_aUEntry, aEnt.getStr(), 32 ); 1401*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1402*cdf0e10cSrcweir else 1403*cdf0e10cSrcweir { 1404*cdf0e10cSrcweir fprintf( stderr, "U entry has length %d, should be 32 <", (int)aEnt.getLength() ); 1405*cdf0e10cSrcweir for( int i = 0; i < aEnt.getLength(); i++ ) 1406*cdf0e10cSrcweir fprintf( stderr, " %.2X", (unsigned int)sal_uInt8(aEnt.getStr()[i]) ); 1407*cdf0e10cSrcweir fprintf( stderr, ">\n" ); 1408*cdf0e10cSrcweir } 1409*cdf0e10cSrcweir #endif 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir } 1412*cdf0e10cSrcweir if( r_ent != pDict->m_aMap.end() ) 1413*cdf0e10cSrcweir { 1414*cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(r_ent->second); 1415*cdf0e10cSrcweir if( pNum ) 1416*cdf0e10cSrcweir m_pData->m_nStandardRevision = static_cast<sal_uInt32>(pNum->m_fValue); 1417*cdf0e10cSrcweir } 1418*cdf0e10cSrcweir if( p_ent != pDict->m_aMap.end() ) 1419*cdf0e10cSrcweir { 1420*cdf0e10cSrcweir PDFNumber* pNum = dynamic_cast<PDFNumber*>(p_ent->second); 1421*cdf0e10cSrcweir if( pNum ) 1422*cdf0e10cSrcweir m_pData->m_nPEntry = static_cast<sal_uInt32>(static_cast<sal_Int32>(pNum->m_fValue)); 1423*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1424*cdf0e10cSrcweir fprintf( stderr, "p entry is %p\n", (void*)m_pData->m_nPEntry ); 1425*cdf0e10cSrcweir #endif 1426*cdf0e10cSrcweir } 1427*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1428*cdf0e10cSrcweir fprintf( stderr, "Encryption dict: sec handler: %s, version = %d, revision = %d, key length = %d\n", 1429*cdf0e10cSrcweir pFilter ? OUStringToOString( pFilter->getFilteredName(), RTL_TEXTENCODING_UTF8 ).getStr() : "<unknown>", 1430*cdf0e10cSrcweir (int)m_pData->m_nAlgoVersion, (int)m_pData->m_nStandardRevision, (int)m_pData->m_nKeyLength ); 1431*cdf0e10cSrcweir #endif 1432*cdf0e10cSrcweir break; 1433*cdf0e10cSrcweir } 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir } 1436*cdf0e10cSrcweir } 1437*cdf0e10cSrcweir } 1438*cdf0e10cSrcweir 1439*cdf0e10cSrcweir return m_pData; 1440*cdf0e10cSrcweir } 1441*cdf0e10cSrcweir 1442*cdf0e10cSrcweir bool PDFFile::emit( EmitContext& rWriteContext ) const 1443*cdf0e10cSrcweir { 1444*cdf0e10cSrcweir setEmitData( rWriteContext, new EmitImplData( this ) ); 1445*cdf0e10cSrcweir 1446*cdf0e10cSrcweir OStringBuffer aBuf( 32 ); 1447*cdf0e10cSrcweir aBuf.append( "%PDF-" ); 1448*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nMajor ) ); 1449*cdf0e10cSrcweir aBuf.append( '.' ); 1450*cdf0e10cSrcweir aBuf.append( sal_Int32( m_nMinor ) ); 1451*cdf0e10cSrcweir aBuf.append( "\n" ); 1452*cdf0e10cSrcweir if( ! rWriteContext.write( aBuf.getStr(), aBuf.getLength() ) ) 1453*cdf0e10cSrcweir return false; 1454*cdf0e10cSrcweir return emitSubElements( rWriteContext ); 1455*cdf0e10cSrcweir } 1456*cdf0e10cSrcweir 1457*cdf0e10cSrcweir PDFEntry* PDFFile::clone() const 1458*cdf0e10cSrcweir { 1459*cdf0e10cSrcweir PDFFile* pNewFl = new PDFFile(); 1460*cdf0e10cSrcweir pNewFl->m_nMajor = m_nMajor; 1461*cdf0e10cSrcweir pNewFl->m_nMinor = m_nMinor; 1462*cdf0e10cSrcweir cloneSubElements( pNewFl->m_aSubElements ); 1463*cdf0e10cSrcweir return pNewFl; 1464*cdf0e10cSrcweir } 1465*cdf0e10cSrcweir 1466*cdf0e10cSrcweir PDFPart::~PDFPart() 1467*cdf0e10cSrcweir { 1468*cdf0e10cSrcweir } 1469*cdf0e10cSrcweir 1470*cdf0e10cSrcweir bool PDFPart::emit( EmitContext& rWriteContext ) const 1471*cdf0e10cSrcweir { 1472*cdf0e10cSrcweir return emitSubElements( rWriteContext ); 1473*cdf0e10cSrcweir } 1474*cdf0e10cSrcweir 1475*cdf0e10cSrcweir PDFEntry* PDFPart::clone() const 1476*cdf0e10cSrcweir { 1477*cdf0e10cSrcweir PDFPart* pNewPt = new PDFPart(); 1478*cdf0e10cSrcweir cloneSubElements( pNewPt->m_aSubElements ); 1479*cdf0e10cSrcweir return pNewPt; 1480*cdf0e10cSrcweir } 1481*cdf0e10cSrcweir 1482