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