LibreOffice Module sdext (master)  1
filterdet.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include "filterdet.hxx"
22 #include "inc/pdfihelper.hxx"
23 #include "inc/pdfparse.hxx"
24 
25 #include <osl/file.h>
26 #include <osl/thread.h>
27 #include <rtl/digest.h>
28 #include <sal/log.hxx>
29 #include <com/sun/star/io/IOException.hpp>
30 #include <com/sun/star/io/XInputStream.hpp>
31 #include <com/sun/star/io/XStream.hpp>
32 #include <com/sun/star/io/XSeekable.hpp>
33 #include <com/sun/star/io/TempFile.hpp>
34 #include <com/sun/star/task/XInteractionHandler.hpp>
35 #include <comphelper/fileurl.hxx>
36 #include <comphelper/hash.hxx>
38 #include <tools/diagnose_ex.h>
39 #include <memory>
40 #include <string.h>
41 
42 using namespace com::sun::star;
43 
44 namespace pdfi
45 {
46 
47 // TODO(T3): locking/thread safety
48 
49 namespace {
50 
51 class FileEmitContext : public pdfparse::EmitContext
52 {
53 private:
54  oslFileHandle m_aReadHandle;
55  unsigned int m_nReadLen;
56  uno::Reference< io::XStream > m_xContextStream;
57  uno::Reference< io::XSeekable > m_xSeek;
58  uno::Reference< io::XOutputStream > m_xOut;
59 
60 public:
61  FileEmitContext( const OUString& rOrigFile,
62  const uno::Reference< uno::XComponentContext >& xContext,
63  const pdfparse::PDFContainer* pTop );
64  virtual ~FileEmitContext() override;
65 
66  virtual bool write( const void* pBuf, unsigned int nLen ) override;
67  virtual unsigned int getCurPos() override;
68  virtual bool copyOrigBytes( unsigned int nOrigOffset, unsigned int nLen ) override;
69  virtual unsigned int readOrigBytes( unsigned int nOrigOffset, unsigned int nLen, void* pBuf ) override;
70 
71  const uno::Reference< io::XStream >& getContextStream() const { return m_xContextStream; }
72 };
73 
74 }
75 
76 FileEmitContext::FileEmitContext( const OUString& rOrigFile,
77  const uno::Reference< uno::XComponentContext >& xContext,
78  const pdfparse::PDFContainer* pTop ) :
79  pdfparse::EmitContext( pTop ),
80  m_aReadHandle(nullptr),
81  m_nReadLen(0)
82 {
83  m_xContextStream.set( io::TempFile::create(xContext), uno::UNO_QUERY_THROW );
84  m_xOut = m_xContextStream->getOutputStream();
85  m_xSeek.set(m_xOut, uno::UNO_QUERY_THROW );
86 
87  if( osl_openFile( rOrigFile.pData,
89  osl_File_OpenFlag_Read ) == osl_File_E_None )
90  {
91  oslFileError aErr = osl_setFilePos( m_aReadHandle, osl_Pos_End, 0 );
92  if( aErr == osl_File_E_None )
93  {
94  sal_uInt64 nFileSize = 0;
95  if( (aErr=osl_getFilePos( m_aReadHandle,
96  &nFileSize )) == osl_File_E_None )
97  {
98  m_nReadLen = static_cast<unsigned int>(nFileSize);
99  }
100  }
101  if( aErr != osl_File_E_None )
102  {
103  osl_closeFile( m_aReadHandle );
104  m_aReadHandle = nullptr;
105  }
106  }
107  m_bDeflate = true;
108 }
109 
110 FileEmitContext::~FileEmitContext()
111 {
112  if( m_aReadHandle )
113  osl_closeFile( m_aReadHandle );
114 }
115 
116 bool FileEmitContext::write( const void* pBuf, unsigned int nLen )
117 {
118  if( ! m_xOut.is() )
119  return false;
120 
121  uno::Sequence< sal_Int8 > aSeq( nLen );
122  memcpy( aSeq.getArray(), pBuf, nLen );
123  m_xOut->writeBytes( aSeq );
124  return true;
125 }
126 
127 unsigned int FileEmitContext::getCurPos()
128 {
129  unsigned int nPos = 0;
130  if( m_xSeek.is() )
131  {
132  nPos = static_cast<unsigned int>( m_xSeek->getPosition() );
133  }
134  return nPos;
135 }
136 
137 bool FileEmitContext::copyOrigBytes( unsigned int nOrigOffset, unsigned int nLen )
138 {
139  if( nOrigOffset + nLen > m_nReadLen )
140  return false;
141 
142  if( osl_setFilePos( m_aReadHandle, osl_Pos_Absolut, nOrigOffset ) != osl_File_E_None )
143  return false;
144 
145  uno::Sequence< sal_Int8 > aSeq( nLen );
146 
147  sal_uInt64 nBytesRead = 0;
148  if( osl_readFile( m_aReadHandle,
149  aSeq.getArray(),
150  nLen,
151  &nBytesRead ) != osl_File_E_None
152  || nBytesRead != static_cast<sal_uInt64>(nLen) )
153  {
154  return false;
155  }
156 
157  m_xOut->writeBytes( aSeq );
158  return true;
159 }
160 
161 unsigned int FileEmitContext::readOrigBytes( unsigned int nOrigOffset, unsigned int nLen, void* pBuf )
162 {
163  if( nOrigOffset + nLen > m_nReadLen )
164  return 0;
165 
166  if( osl_setFilePos( m_aReadHandle,
167  osl_Pos_Absolut,
168  nOrigOffset ) != osl_File_E_None )
169  {
170  return 0;
171  }
172 
173  sal_uInt64 nBytesRead = 0;
174  if( osl_readFile( m_aReadHandle,
175  pBuf,
176  nLen,
177  &nBytesRead ) != osl_File_E_None )
178  {
179  return 0;
180  }
181  return static_cast<unsigned int>(nBytesRead);
182 }
183 
184 
185 PDFDetector::PDFDetector( const uno::Reference< uno::XComponentContext >& xContext) :
187  m_xContext( xContext )
188 {}
189 
190 // XExtendedFilterDetection
191 OUString SAL_CALL PDFDetector::detect( uno::Sequence< beans::PropertyValue >& rFilterData )
192 {
193  osl::MutexGuard const guard( m_aMutex );
194  bool bSuccess = false;
195 
196  // get the InputStream carrying the PDF content
197  uno::Reference< io::XInputStream > xInput;
198  uno::Reference< io::XStream > xEmbedStream;
199  OUString aOutFilterName, aOutTypeName;
200  OUString aURL;
201  OUString aPwd;
202  const beans::PropertyValue* pAttribs = rFilterData.getConstArray();
203  sal_Int32 nAttribs = rFilterData.getLength();
204  sal_Int32 nFilterNamePos = -1;
205  sal_Int32 nPwdPos = -1;
206  for( sal_Int32 i = 0; i < nAttribs; i++ )
207  {
208  OUString aVal( "<no string>" );
209  pAttribs[i].Value >>= aVal;
210  SAL_INFO( "sdext.pdfimport", "doDetection: Attrib: " + pAttribs[i].Name + " = " + aVal);
211 
212  if ( pAttribs[i].Name == "InputStream" )
213  pAttribs[i].Value >>= xInput;
214  else if ( pAttribs[i].Name == "URL" )
215  pAttribs[i].Value >>= aURL;
216  else if ( pAttribs[i].Name == "FilterName" )
217  nFilterNamePos = i;
218  else if ( pAttribs[i].Name == "Password" )
219  {
220  nPwdPos = i;
221  pAttribs[i].Value >>= aPwd;
222  }
223  }
224  if( xInput.is() )
225  {
226  oslFileHandle aFile = nullptr;
227  try {
228  uno::Reference< io::XSeekable > xSeek( xInput, uno::UNO_QUERY );
229  if( xSeek.is() )
230  xSeek->seek( 0 );
231  // read the first 1024 byte (see PDF reference implementation note 12)
232  const sal_Int32 nHeaderSize = 1024;
233  uno::Sequence< sal_Int8 > aBuf( nHeaderSize );
234  sal_uInt64 nBytes = xInput->readBytes( aBuf, nHeaderSize );
235  if( nBytes > 5 )
236  {
237  const sal_Int8* pBytes = aBuf.getConstArray();
238  for( sal_uInt64 i = 0; i < nBytes-5; i++ )
239  {
240  if( pBytes[i] == '%' &&
241  pBytes[i+1] == 'P' &&
242  pBytes[i+2] == 'D' &&
243  pBytes[i+3] == 'F' &&
244  pBytes[i+4] == '-' )
245  {
246  bSuccess = true;
247  break;
248  }
249  }
250  }
251 
252  // check for hybrid PDF
253  if( bSuccess &&
254  ( aURL.isEmpty() || !comphelper::isFileUrl(aURL) )
255  )
256  {
257  sal_uInt64 nWritten = 0;
258  if( osl_createTempFile( nullptr, &aFile, &aURL.pData ) != osl_File_E_None )
259  {
260  bSuccess = false;
261  }
262  else
263  {
264  SAL_INFO( "sdext.pdfimport", "created temp file " + aURL );
265 
266  osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten );
267 
268  SAL_WARN_IF( nWritten != nBytes, "sdext.pdfimport", "writing of header bytes failed" );
269 
270  if( nWritten == nBytes )
271  {
272  const sal_uInt32 nBufSize = 4096;
273  aBuf = uno::Sequence<sal_Int8>(nBufSize);
274  // copy the bytes
275  do
276  {
277  nBytes = xInput->readBytes( aBuf, nBufSize );
278  if( nBytes > 0 )
279  {
280  osl_writeFile( aFile, aBuf.getConstArray(), nBytes, &nWritten );
281  if( nWritten != nBytes )
282  {
283  bSuccess = false;
284  break;
285  }
286  }
287  } while( nBytes == nBufSize );
288  }
289  }
290  osl_closeFile( aFile );
291  }
292  } catch (const css::io::IOException &) {
293  TOOLS_WARN_EXCEPTION("sdext.pdfimport", "caught");
294  return OUString();
295  }
296  OUString aEmbedMimetype;
297  xEmbedStream = getAdditionalStream( aURL, aEmbedMimetype, aPwd, m_xContext, rFilterData, false );
298  if( aFile )
299  osl_removeFile( aURL.pData );
300  if( !aEmbedMimetype.isEmpty() )
301  {
302  if( aEmbedMimetype == "application/vnd.oasis.opendocument.text"
303  || aEmbedMimetype == "application/vnd.oasis.opendocument.text-master" )
304  aOutFilterName = "writer_pdf_addstream_import";
305  else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.presentation" )
306  aOutFilterName = "impress_pdf_addstream_import";
307  else if( aEmbedMimetype == "application/vnd.oasis.opendocument.graphics"
308  || aEmbedMimetype == "application/vnd.oasis.opendocument.drawing" )
309  aOutFilterName = "draw_pdf_addstream_import";
310  else if ( aEmbedMimetype == "application/vnd.oasis.opendocument.spreadsheet" )
311  aOutFilterName = "calc_pdf_addstream_import";
312  }
313  }
314 
315  if( bSuccess )
316  {
317  if( !aOutFilterName.isEmpty() )
318  {
319  if( nFilterNamePos == -1 )
320  {
321  nFilterNamePos = nAttribs;
322  rFilterData.realloc( ++nAttribs );
323  rFilterData.getArray()[ nFilterNamePos ].Name = "FilterName";
324  }
325  auto pFilterData = rFilterData.getArray();
326  aOutTypeName = "pdf_Portable_Document_Format";
327 
328  pFilterData[nFilterNamePos].Value <<= aOutFilterName;
329  if( xEmbedStream.is() )
330  {
331  rFilterData.realloc( ++nAttribs );
332  pFilterData = rFilterData.getArray();
333  pFilterData[nAttribs-1].Name = "EmbeddedSubstream";
334  pFilterData[nAttribs-1].Value <<= xEmbedStream;
335  }
336  if( !aPwd.isEmpty() )
337  {
338  if( nPwdPos == -1 )
339  {
340  nPwdPos = nAttribs;
341  rFilterData.realloc( ++nAttribs );
342  pFilterData = rFilterData.getArray();
343  pFilterData[ nPwdPos ].Name = "Password";
344  }
345  pFilterData[ nPwdPos ].Value <<= aPwd;
346  }
347  }
348  else
349  {
350  css::beans::PropertyValue* pFilterData;
351  if( nFilterNamePos == -1 )
352  {
353  nFilterNamePos = nAttribs;
354  rFilterData.realloc( ++nAttribs );
355  pFilterData = rFilterData.getArray();
356  pFilterData[ nFilterNamePos ].Name = "FilterName";
357  }
358  else
359  pFilterData = rFilterData.getArray();
360 
361  const sal_Int32 nDocumentType = 0; //const sal_Int32 nDocumentType = queryDocumentTypeDialog(m_xContext,aURL);
362  if( nDocumentType < 0 )
363  {
364  return OUString();
365  }
366  else switch( nDocumentType )
367  {
368  case 0:
369  pFilterData[nFilterNamePos].Value <<= OUString( "draw_pdf_import" );
370  break;
371 
372  case 1:
373  pFilterData[nFilterNamePos].Value <<= OUString( "impress_pdf_import" );
374  break;
375 
376  case 2:
377  pFilterData[nFilterNamePos].Value <<= OUString( "writer_pdf_import" );
378  break;
379 
380  default:
381  assert(!"Unexpected case");
382  }
383 
384  aOutTypeName = "pdf_Portable_Document_Format";
385  }
386  }
387 
388  return aOutTypeName;
389 }
390 
392 {
393  return "org.libreoffice.comp.documents.PDFDetector";
394 }
395 
396 sal_Bool PDFDetector::supportsService(OUString const & ServiceName)
397 {
398  return cppu::supportsService(this, ServiceName);
399 }
400 
401 css::uno::Sequence<OUString> PDFDetector::getSupportedServiceNames()
402 {
403  return {"com.sun.star.document.ImportFilter"};
404 }
405 
406 bool checkDocChecksum( const OUString& rInPDFFileURL,
407  sal_uInt32 nBytes,
408  const OUString& rChkSum )
409 {
410  if( rChkSum.getLength() != 2* RTL_DIGEST_LENGTH_MD5 )
411  {
412  SAL_INFO(
413  "sdext.pdfimport",
414  "checksum of length " << rChkSum.getLength() << ", expected "
415  << 2*RTL_DIGEST_LENGTH_MD5);
416  return false;
417  }
418 
419  // prepare checksum to test
420  sal_uInt8 nTestChecksum[ RTL_DIGEST_LENGTH_MD5 ];
421  const sal_Unicode* pChar = rChkSum.getStr();
422  for(sal_uInt8 & rn : nTestChecksum)
423  {
424  sal_uInt8 nByte = sal_uInt8( ( (*pChar >= '0' && *pChar <= '9') ? *pChar - '0' :
425  ( (*pChar >= 'A' && *pChar <= 'F') ? *pChar - 'A' + 10 :
426  ( (*pChar >= 'a' && *pChar <= 'f') ? *pChar - 'a' + 10 :
427  0 ) ) ) );
428  nByte <<= 4;
429  pChar++;
430  nByte |= ( (*pChar >= '0' && *pChar <= '9') ? *pChar - '0' :
431  ( (*pChar >= 'A' && *pChar <= 'F') ? *pChar - 'A' + 10 :
432  ( (*pChar >= 'a' && *pChar <= 'f') ? *pChar - 'a' + 10 :
433  0 ) ) );
434  pChar++;
435  rn = nByte;
436  }
437 
438  // open file and calculate actual checksum up to index nBytes
439  ::std::vector<unsigned char> nChecksum;
441  oslFileHandle aRead = nullptr;
442  if( osl_openFile(rInPDFFileURL.pData,
443  &aRead,
444  osl_File_OpenFlag_Read ) == osl_File_E_None )
445  {
446  sal_uInt8 aBuf[4096];
447  sal_uInt32 nCur = 0;
448  sal_uInt64 nBytesRead = 0;
449  while( nCur < nBytes )
450  {
451  sal_uInt32 nPass = std::min<sal_uInt32>(nBytes - nCur, sizeof( aBuf ));
452  if( osl_readFile( aRead, aBuf, nPass, &nBytesRead) != osl_File_E_None
453  || nBytesRead == 0 )
454  {
455  break;
456  }
457  nPass = static_cast<sal_uInt32>(nBytesRead);
458  nCur += nPass;
459  aDigest.update(aBuf, nPass);
460  }
461 
462  nChecksum = aDigest.finalize();
463  osl_closeFile( aRead );
464  }
465 
466  // compare the contents
467  return nChecksum.size() == RTL_DIGEST_LENGTH_MD5
468  && (0 == memcmp(nChecksum.data(), nTestChecksum, nChecksum.size()));
469 }
470 
471 uno::Reference< io::XStream > getAdditionalStream( const OUString& rInPDFFileURL,
472  OUString& rOutMimetype,
473  OUString& io_rPwd,
474  const uno::Reference<uno::XComponentContext>& xContext,
475  const uno::Sequence<beans::PropertyValue>& rFilterData,
476  bool bMayUseUI )
477 {
478  uno::Reference< io::XStream > xEmbed;
479  OString aPDFFile;
480  OUString aSysUPath;
481  if( osl_getSystemPathFromFileURL( rInPDFFileURL.pData, &aSysUPath.pData ) != osl_File_E_None )
482  return xEmbed;
483  aPDFFile = OUStringToOString( aSysUPath, osl_getThreadTextEncoding() );
484 
485  std::unique_ptr<pdfparse::PDFEntry> pEntry( pdfparse::PDFReader::read( aPDFFile.getStr() ));
486  if( pEntry )
487  {
488  pdfparse::PDFFile* pPDFFile = dynamic_cast<pdfparse::PDFFile*>(pEntry.get());
489  if( pPDFFile )
490  {
491  unsigned int nElements = pPDFFile->m_aSubElements.size();
492  while( nElements-- > 0 )
493  {
494  pdfparse::PDFTrailer* pTrailer = dynamic_cast<pdfparse::PDFTrailer*>(pPDFFile->m_aSubElements[nElements].get());
495  if( pTrailer && pTrailer->m_pDict )
496  {
497  // search document checksum entry
498  auto chk = pTrailer->m_pDict->m_aMap.find( "DocChecksum" );
499  if( chk == pTrailer->m_pDict->m_aMap.end() )
500  {
501  SAL_INFO( "sdext.pdfimport", "no DocChecksum entry" );
502  continue;
503  }
504  pdfparse::PDFName* pChkSumName = dynamic_cast<pdfparse::PDFName*>(chk->second);
505  if( pChkSumName == nullptr )
506  {
507  SAL_INFO( "sdext.pdfimport", "no name for DocChecksum entry" );
508  continue;
509  }
510 
511  // search for AdditionalStreams entry
512  auto add_stream = pTrailer->m_pDict->m_aMap.find( "AdditionalStreams" );
513  if( add_stream == pTrailer->m_pDict->m_aMap.end() )
514  {
515  SAL_INFO( "sdext.pdfimport", "no AdditionalStreams entry" );
516  continue;
517  }
518  pdfparse::PDFArray* pStreams = dynamic_cast<pdfparse::PDFArray*>(add_stream->second);
519  if( ! pStreams || pStreams->m_aSubElements.size() < 2 )
520  {
521  SAL_INFO( "sdext.pdfimport", "AdditionalStreams array too small" );
522  continue;
523  }
524 
525  // check checksum
526  OUString aChkSum = pChkSumName->getFilteredName();
527  if( ! checkDocChecksum( rInPDFFileURL, pTrailer->m_nOffset, aChkSum ) )
528  continue;
529 
530  // extract addstream and mimetype
531  pdfparse::PDFName* pMimeType = dynamic_cast<pdfparse::PDFName*>(pStreams->m_aSubElements[0].get());
532  pdfparse::PDFObjectRef* pStreamRef = dynamic_cast<pdfparse::PDFObjectRef*>(pStreams->m_aSubElements[1].get());
533 
534  SAL_WARN_IF( !pMimeType, "sdext.pdfimport", "error: no mimetype element" );
535  SAL_WARN_IF( !pStreamRef, "sdext.pdfimport", "error: no stream ref element" );
536 
537  if( pMimeType && pStreamRef )
538  {
539  pdfparse::PDFObject* pObject = pPDFFile->findObject( pStreamRef->m_nNumber, pStreamRef->m_nGeneration );
540  SAL_WARN_IF( !pObject, "sdext.pdfimport", "object not found" );
541  if( pObject )
542  {
543  if( pPDFFile->isEncrypted() )
544  {
545  bool bAuthenticated = false;
546  if( !io_rPwd.isEmpty() )
547  {
548  OString aIsoPwd = OUStringToOString( io_rPwd,
549  RTL_TEXTENCODING_ISO_8859_1 );
550  bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
551  }
552  if( ! bAuthenticated )
553  {
554  uno::Reference< task::XInteractionHandler > xIntHdl;
555  for( const beans::PropertyValue& rAttrib : rFilterData )
556  {
557  if ( rAttrib.Name == "InteractionHandler" )
558  rAttrib.Value >>= xIntHdl;
559  }
560  if( ! bMayUseUI || ! xIntHdl.is() )
561  {
562  rOutMimetype = pMimeType->getFilteredName();
563  xEmbed.clear();
564  break;
565  }
566 
567  OUString aDocName( rInPDFFileURL.copy( rInPDFFileURL.lastIndexOf( '/' )+1 ) );
568 
569  bool bEntered = false;
570  do
571  {
572  bEntered = getPassword( xIntHdl, io_rPwd, ! bEntered, aDocName );
573  OString aIsoPwd = OUStringToOString( io_rPwd,
574  RTL_TEXTENCODING_ISO_8859_1 );
575  bAuthenticated = pPDFFile->setupDecryptionData( aIsoPwd.getStr() );
576  } while( bEntered && ! bAuthenticated );
577  }
578 
579  if( ! bAuthenticated )
580  continue;
581  }
582  rOutMimetype = pMimeType->getFilteredName();
583  FileEmitContext aContext( rInPDFFileURL,
584  xContext,
585  pPDFFile );
586  aContext.m_bDecrypt = pPDFFile->isEncrypted();
587  pObject->writeStream( aContext, pPDFFile );
588  xEmbed = aContext.getContextStream();
589  break; // success
590  }
591  }
592  }
593  }
594  }
595  }
596 
597  return xEmbed;
598 }
599 
600 
601 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
603  css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any> const&)
604 {
605  return cppu::acquire(new PDFDetector(context));
606 }
607 
608 }
609 
610 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
URL aURL
signed char sal_Int8
static std::unique_ptr< PDFEntry > read(const char *pFileName)
Definition: pdfparse.cxx:608
PDFObject * findObject(unsigned int nNumber, unsigned int nGeneration) const
Definition: pdfentries.cxx:475
unsigned int m_nNumber
Definition: pdfparse.hxx:139
aBuf
mutable::osl::Mutex m_aMutex
OUString Name
unsigned int m_nGeneration
Definition: pdfparse.hxx:140
EmbeddedObjectRef * pObject
std::vector< std::unique_ptr< PDFEntry > > m_aSubElements
Definition: pdfparse.hxx:161
sal_uInt16 sal_Unicode
uno::Reference< io::XStream > getAdditionalStream(const OUString &rInPDFFileURL, OUString &rOutMimetype, OUString &io_rPwd, const uno::Reference< uno::XComponentContext > &xContext, const uno::Sequence< beans::PropertyValue > &rFilterData, bool bMayUseUI)
Definition: filterdet.cxx:471
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
std::mutex m_aMutex
bool checkDocChecksum(const OUString &rInPDFFileURL, sal_uInt32 nBytes, const OUString &rChkSum)
Definition: filterdet.cxx:406
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_Int32 nElements
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * sdext_PDFDetector_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Definition: filterdet.cxx:602
::cppu::WeakComponentImplHelper< css::document::XExtendedFilterDetection, css::lang::XServiceInfo > PDFDetectorBase
Definition: filterdet.hxx:35
OUString getFilteredName() const
Definition: pdfentries.cxx:157
uno::Reference< io::XOutputStream > m_xOut
Definition: filterdet.cxx:58
#define TOOLS_WARN_EXCEPTION(area, stream)
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: filterdet.cxx:401
int i
oslFileHandle m_aReadHandle
Definition: filterdet.cxx:54
unsigned int m_nReadLen
Definition: filterdet.cxx:55
unsigned char sal_Bool
bool isEncrypted() const
bool getPassword(const css::uno::Reference< css::task::XInteractionHandler > &xHandler, OUString &rOutPwd, bool bFirstTry, const OUString &rDocName)
retrieve password from user
css::uno::Reference< css::uno::XComponentContext > m_xContext
Definition: filterdet.hxx:42
uno::Reference< io::XSeekable > m_xSeek
Definition: filterdet.cxx:57
uno::Reference< io::XStream > m_xContextStream
Definition: filterdet.cxx:56
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
void update(const unsigned char *pInput, size_t length)
COMPHELPER_DLLPUBLIC bool isFileUrl(OUString const &url)
#define SAL_INFO(area, stream)
Sequence< sal_Int8 > aSeq
const char * pChar
virtual OUString SAL_CALL detect(css::uno::Sequence< css::beans::PropertyValue > &io_rDescriptor) override
Definition: filterdet.cxx:191
bool setupDecryptionData(const OString &rPwd) const
std::vector< unsigned char > finalize()
OUString SAL_CALL getImplementationName() override
Definition: filterdet.cxx:391
sal_uInt16 nPos
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
Definition: filterdet.cxx:396
const uno::Reference< uno::XComponentContext > m_xContext
Definition: wrapper.cxx:151
void writeStream(EmitContext &rContext, const PDFFile *pPDFFile) const
Definition: pdfentries.cxx:782