mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Create ChangePassword for pdf
This commit is contained in:
@ -54,6 +54,7 @@
|
||||
#include "SrcWriter/Info.h"
|
||||
#include "SrcWriter/Annotation.h"
|
||||
#include "SrcWriter/ResourcesDictionary.h"
|
||||
#include "SrcWriter/Streams.h"
|
||||
|
||||
#define AddToObject(oVal)\
|
||||
{\
|
||||
@ -1441,6 +1442,191 @@ void CPdfFile::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD
|
||||
return;
|
||||
m_pInternal->pWriter->AddMetaData(sMetaName, pMetaData, nMetaLength);
|
||||
}
|
||||
HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword)
|
||||
{
|
||||
RELEASEOBJECT(m_pInternal->pWriter);
|
||||
m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false);
|
||||
|
||||
PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument();
|
||||
if (!pPDFDocument)
|
||||
return S_FALSE;
|
||||
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
if (!xref)
|
||||
return S_FALSE;
|
||||
Object* trailerDict = xref->getTrailerDict();
|
||||
if (!trailerDict)
|
||||
return S_FALSE;
|
||||
|
||||
PdfWriter::CDocument* pDoc = m_pInternal->pWriter->m_pDocument;
|
||||
PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, 0);
|
||||
PdfWriter::CXref* m_pXref = new PdfWriter::CXref(pDoc, xref->getNumObjects()); // Для новых объектов
|
||||
if (!xref || !pDoc || !pXref || !m_pXref)
|
||||
{
|
||||
RELEASEOBJECT(pXref);
|
||||
RELEASEOBJECT(m_pXref);
|
||||
return S_FALSE;
|
||||
}
|
||||
pXref->SetPrev(m_pXref);
|
||||
|
||||
for (int i = 0; i < xref->getSize(); ++i)
|
||||
{
|
||||
XRefEntry* pEntry = xref->getEntry(i);
|
||||
if (pEntry->type == xrefEntryFree)
|
||||
continue;
|
||||
|
||||
if (i != pXref->GetSizeXRef())
|
||||
{
|
||||
PdfWriter::CXref* pXref2 = new PdfWriter::CXref(pDoc, i);
|
||||
pXref2->SetPrev(pXref);
|
||||
pXref = pXref2;
|
||||
}
|
||||
|
||||
Object oTemp;
|
||||
xref->fetch(i, pEntry->gen, &oTemp);
|
||||
PdfWriter::CObjectBase* pObj = NULL;
|
||||
|
||||
switch (oTemp.getType())
|
||||
{
|
||||
case objBool:
|
||||
{
|
||||
pObj = new PdfWriter::CBoolObject(oTemp.getBool());
|
||||
break;
|
||||
}
|
||||
case objInt:
|
||||
{
|
||||
pObj = new PdfWriter::CNumberObject(oTemp.getInt());
|
||||
break;
|
||||
}
|
||||
case objReal:
|
||||
{
|
||||
pObj = new PdfWriter::CRealObject(oTemp.getReal());
|
||||
break;
|
||||
}
|
||||
case objString:
|
||||
{
|
||||
TextString* s = new TextString(oTemp.getString());
|
||||
std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength());
|
||||
pObj = new PdfWriter::CStringObject(sValue.c_str());
|
||||
delete s;
|
||||
break;
|
||||
}
|
||||
case objName:
|
||||
{
|
||||
pObj = new PdfWriter::CNameObject(oTemp.getName());
|
||||
break;
|
||||
}
|
||||
case objNull:
|
||||
{
|
||||
pObj = new PdfWriter::CNullObject();
|
||||
break;
|
||||
}
|
||||
case objArray:
|
||||
{
|
||||
pObj = new PdfWriter::CArrayObject();
|
||||
|
||||
for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex)
|
||||
{
|
||||
Object oT;
|
||||
oTemp.arrayGetNF(nIndex, &oT);
|
||||
DictToCDictObject(&oT, pObj, false, "");
|
||||
oT.free();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case objDict:
|
||||
{
|
||||
pObj = new PdfWriter::CDictObject();
|
||||
|
||||
for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oT;
|
||||
char* chKey = oTemp.dictGetKey(nIndex);
|
||||
oTemp.dictGetValNF(nIndex, &oT);
|
||||
DictToCDictObject(&oT, pObj, false, chKey);
|
||||
oT.free();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case objRef:
|
||||
{
|
||||
PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase();
|
||||
pBase->SetRef(oTemp.getRefNum(), oTemp.getRefGen());
|
||||
pObj = new PdfWriter::CProxyObject(pBase, true);
|
||||
break;
|
||||
}
|
||||
case objStream:
|
||||
{
|
||||
Dict* pDict = oTemp.streamGetDict();
|
||||
Object oObjStm;
|
||||
if (pDict->lookup("Type", &oObjStm)->isName("ObjStm"))
|
||||
{
|
||||
oObjStm.free();
|
||||
break;
|
||||
}
|
||||
oObjStm.free();
|
||||
|
||||
PdfWriter::CDictObject* pDObj = new PdfWriter::CDictObject();
|
||||
pObj = pDObj;
|
||||
|
||||
int nLength = 0;
|
||||
for (int nIndex = 0; nIndex < pDict->getLength(); ++nIndex)
|
||||
{
|
||||
Object oT;
|
||||
char* chKey = pDict->getKey(nIndex);
|
||||
if (strcmp("Length", chKey) == 0)
|
||||
{
|
||||
Object oLength;
|
||||
nLength = pDict->getVal(nIndex, &oLength)->isInt() ? oLength.getInt() : 0;
|
||||
oLength.free();
|
||||
continue;
|
||||
}
|
||||
pDict->getValNF(nIndex, &oT);
|
||||
DictToCDictObject(&oT, pObj, false, chKey);
|
||||
oT.free();
|
||||
}
|
||||
|
||||
PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream();
|
||||
pDObj->SetStream(m_pXref, pStream, false);
|
||||
|
||||
Stream* pImage = oTemp.getStream()->getUndecodedStream();
|
||||
pImage->reset();
|
||||
for (int nI = 0; nI < nLength; ++nI)
|
||||
pStream->WriteChar(pImage->getChar());
|
||||
break;
|
||||
}
|
||||
case objNone:
|
||||
case objCmd:
|
||||
case objError:
|
||||
case objEOF:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
oTemp.free();
|
||||
|
||||
if (pObj)
|
||||
pXref->Add(pObj);
|
||||
}
|
||||
|
||||
PdfWriter::CDictObject* pTrailer = pXref->GetTrailer();
|
||||
for (int nIndex = 0; nIndex < trailerDict->dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oTemp;
|
||||
char* chKey = trailerDict->dictGetKey(nIndex);
|
||||
if (strcmp("Root", chKey) == 0 || strcmp("Info", chKey) == 0)
|
||||
{
|
||||
trailerDict->dictGetValNF(nIndex, &oTemp);
|
||||
DictToCDictObject(&oTemp, pTrailer, true, chKey);
|
||||
}
|
||||
oTemp.free();
|
||||
}
|
||||
|
||||
bool bRes = pDoc->SaveNewWithPassword(pXref, m_pXref, wsPath, wsPassword, wsPassword, pTrailer);
|
||||
|
||||
RELEASEOBJECT(pXref);
|
||||
|
||||
return bRes ? S_OK : S_FALSE;
|
||||
}
|
||||
HRESULT CPdfFile::OnlineWordToPdf(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams)
|
||||
{
|
||||
#ifndef BUILDING_WASM_MODULE
|
||||
|
||||
@ -150,6 +150,7 @@ public:
|
||||
void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords);
|
||||
void AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength);
|
||||
|
||||
HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L"");
|
||||
HRESULT OnlineWordToPdf (const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL);
|
||||
HRESULT OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams = NULL);
|
||||
HRESULT AddToPdfFromBinary(BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams = NULL);
|
||||
|
||||
@ -94,7 +94,7 @@ static const long c_BrushTypeRadialGradient = 8002;
|
||||
// CPdfRenderer
|
||||
//
|
||||
//----------------------------------------------------------------------------------------
|
||||
CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer) : m_oCommandManager(this)
|
||||
CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRenderer* pRenderer, bool bCreate) : m_oCommandManager(this)
|
||||
{
|
||||
// Создаем менеджер шрифтов с собственным кэшем
|
||||
m_pFontManager = pAppFonts->GenerateFontManager();
|
||||
@ -108,7 +108,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend
|
||||
if (isPDFA)
|
||||
m_pDocument->SetPDFAConformanceMode(true);
|
||||
|
||||
if (!m_pDocument || !m_pDocument->CreateNew())
|
||||
if (!m_pDocument || (bCreate && !m_pDocument->CreateNew()))
|
||||
{
|
||||
SetError();
|
||||
return;
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Aggplus
|
||||
class CPdfWriter
|
||||
{
|
||||
public:
|
||||
CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL);
|
||||
CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true);
|
||||
~CPdfWriter();
|
||||
int SaveToFile(const std::wstring& wsPath);
|
||||
void SetPassword(const std::wstring& wsPassword);
|
||||
|
||||
@ -218,10 +218,10 @@ namespace PdfWriter
|
||||
m_pFreeTypeLibrary = NULL;
|
||||
}
|
||||
}
|
||||
bool CDocument::SaveToFile(const std::wstring& wsPath, bool bAdd)
|
||||
bool CDocument::SaveToFile(const std::wstring& wsPath)
|
||||
{
|
||||
CFileStream* pStream = new CFileStream();
|
||||
if (!pStream || !pStream->OpenFile(wsPath, bAdd))
|
||||
if (!pStream || !pStream->OpenFile(wsPath, true))
|
||||
return false;
|
||||
|
||||
if (m_pJbig2)
|
||||
@ -264,6 +264,32 @@ namespace PdfWriter
|
||||
|
||||
m_pXref->WriteToStream(pStream, pEncrypt);
|
||||
}
|
||||
bool CDocument::SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer)
|
||||
{
|
||||
if (!pXref || !pTrailer || !_pXref)
|
||||
return false;
|
||||
m_pTrailer = pTrailer;
|
||||
|
||||
CEncrypt* pEncrypt = NULL;
|
||||
if (!wsOwnerPassword.empty())
|
||||
{
|
||||
m_pEncryptDict = new CEncryptDict(_pXref);
|
||||
m_pEncryptDict->SetPasswords(wsOwnerPassword, wsUserPassword);
|
||||
m_pTrailer->Add("Encrypt", m_pEncryptDict);
|
||||
|
||||
pEncrypt = m_pEncryptDict->GetEncrypt();
|
||||
PrepareEncryption();
|
||||
}
|
||||
|
||||
CFileStream* pStream = new CFileStream();
|
||||
if (!pStream || !pStream->OpenFile(wsPath, true))
|
||||
return false;
|
||||
pStream->WriteStr(c_sPdfHeader);
|
||||
|
||||
pXref->WriteToStream(pStream, pEncrypt);
|
||||
|
||||
return true;
|
||||
}
|
||||
void CDocument::PrepareEncryption()
|
||||
{
|
||||
CEncrypt* pEncrypt = m_pEncryptDict->GetEncrypt();
|
||||
|
||||
@ -103,7 +103,8 @@ namespace PdfWriter
|
||||
|
||||
bool CreateNew();
|
||||
void Close();
|
||||
bool SaveToFile(const std::wstring& wsPath, bool bAdd = true);
|
||||
bool SaveToFile(const std::wstring& wsPath);
|
||||
bool SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer);
|
||||
|
||||
void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword);
|
||||
void SetPermission(unsigned int unPermission);
|
||||
|
||||
@ -651,7 +651,7 @@ namespace PdfWriter
|
||||
}
|
||||
}
|
||||
}
|
||||
void CDictObject::SetStream(CXref* pXref, CStream* pStream)
|
||||
void CDictObject::SetStream(CXref* pXref, CStream* pStream, bool bThis)
|
||||
{
|
||||
if (m_pStream)
|
||||
delete m_pStream;
|
||||
@ -661,7 +661,8 @@ namespace PdfWriter
|
||||
CNumberObject* pLength = new CNumberObject(0);
|
||||
|
||||
// Только stream object добавляются в таблицу xref автоматически
|
||||
pXref->Add((CObjectBase*)this);
|
||||
if (bThis)
|
||||
pXref->Add((CObjectBase*)this);
|
||||
pXref->Add((CObjectBase*)pLength);
|
||||
|
||||
Add("Length", (CObjectBase*)pLength);
|
||||
@ -852,7 +853,7 @@ namespace PdfWriter
|
||||
unsigned int unMaxObjId = m_pPrev ? pPrev->m_arrEntries.size() + pPrev->m_unStartOffset : m_arrEntries.size() + m_unStartOffset;
|
||||
|
||||
m_pTrailer->Add("Size", unMaxObjId);
|
||||
if (m_pPrev)
|
||||
if (m_pPrev && pPrev->m_unAddr)
|
||||
m_pTrailer->Add("Prev", pPrev->m_unAddr);
|
||||
|
||||
pStream->WriteStr("trailer\012");
|
||||
@ -916,7 +917,7 @@ namespace PdfWriter
|
||||
CDictObject* pTrailer = m_pTrailer;
|
||||
pTrailer->Add("Type", "XRef");
|
||||
pTrailer->Add("Size", unMaxObjId + 1);
|
||||
if (m_pPrev)
|
||||
if (m_pPrev && pPrev->m_unAddr)
|
||||
pTrailer->Add("Prev", pPrev->m_unAddr);
|
||||
CArrayObject* pW = new CArrayObject();
|
||||
pTrailer->Add("W", pW);
|
||||
|
||||
@ -468,7 +468,7 @@ namespace PdfWriter
|
||||
{
|
||||
m_unFilter = unFiler;
|
||||
}
|
||||
void SetStream(CXref* pXref, CStream* pStream);
|
||||
void SetStream(CXref* pXref, CStream* pStream, bool bThis = true);
|
||||
|
||||
virtual void BeforeWrite(){}
|
||||
virtual void Write(CStream* pStream){}
|
||||
|
||||
@ -589,7 +589,6 @@ namespace PdfWriter
|
||||
// Добавляем запись Filter
|
||||
if (pDict->GetStream())
|
||||
{
|
||||
pDict->Remove("Filter");
|
||||
unsigned int unFilter = pDict->GetFilter();
|
||||
if (STREAM_FILTER_NONE != unFilter)
|
||||
{
|
||||
|
||||
@ -281,7 +281,7 @@ TEST_F(CPdfFileTest, EditPdf)
|
||||
|
||||
TEST_F(CPdfFileTest, EditPdfFromBase64)
|
||||
{
|
||||
// GTEST_SKIP();
|
||||
GTEST_SKIP();
|
||||
|
||||
LoadFromFile();
|
||||
ASSERT_TRUE(pdfFile->EditPdf(wsDstFile));
|
||||
@ -368,3 +368,19 @@ TEST_F(CPdfFileTest, EditPdfSign)
|
||||
|
||||
RELEASEOBJECT(pCertificate);
|
||||
}
|
||||
|
||||
TEST_F(CPdfFileTest, ChangePasswordToEmpty)
|
||||
{
|
||||
// GTEST_SKIP();
|
||||
|
||||
LoadFromFile();
|
||||
EXPECT_HRESULT_SUCCEEDED(pdfFile->ChangePassword(wsDstFile));
|
||||
}
|
||||
|
||||
TEST_F(CPdfFileTest, ChangePasswordToPassword)
|
||||
{
|
||||
GTEST_SKIP();
|
||||
|
||||
LoadFromFile();
|
||||
EXPECT_HRESULT_SUCCEEDED(pdfFile->ChangePassword(wsDstFile, L"123456"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user