mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
250 lines
5.5 KiB
C++
250 lines
5.5 KiB
C++
#include "stdafx.h"
|
|
|
|
#include <stddef.h>
|
|
#include "Object.h"
|
|
#include "Array.h"
|
|
#include "Dict.h"
|
|
#include "Decrypt.h"
|
|
#include "Parser.h"
|
|
#include "XRef.h"
|
|
|
|
Parser::Parser(XRef *pXref, Lexer *pLexer, BOOL bAllowStreams)
|
|
{
|
|
m_pXref = pXref;
|
|
m_pLexer = pLexer;
|
|
m_nInlineImage = 0;
|
|
m_bAllowStreams = bAllowStreams;
|
|
m_pLexer->GetObject( &m_oBuffer1 );
|
|
m_pLexer->GetObject( &m_oBuffer2 );
|
|
}
|
|
|
|
Parser::~Parser()
|
|
{
|
|
m_oBuffer1.Free();
|
|
m_oBuffer2.Free();
|
|
delete m_pLexer;
|
|
}
|
|
|
|
Object *Parser::GetObject(Object *pObject, unsigned char *sDecryptKey, CryptAlgorithm eEncryptAlgorithm, int nKeyLength, int nObjectNum, int nObjectGen)
|
|
{
|
|
Stream *pStream = NULL;
|
|
Object oTemp;
|
|
int nNum = 0;
|
|
|
|
// Îáíîâëÿåì áóôôåð ïîñëå Inline image data
|
|
if ( m_nInlineImage == 2 )
|
|
{
|
|
m_oBuffer1.Free();
|
|
m_oBuffer2.Free();
|
|
m_pLexer->GetObject( &m_oBuffer1 );
|
|
m_pLexer->GetObject( &m_oBuffer2 );
|
|
m_nInlineImage = 0;
|
|
}
|
|
|
|
// Ìàññèâ
|
|
if ( m_oBuffer1.IsCommand("[") )
|
|
{
|
|
Shift();
|
|
pObject->InitArray(m_pXref);
|
|
while ( !m_oBuffer1.IsCommand("]" ) && !m_oBuffer1.IsEOF() )
|
|
pObject->ArrayAdd( GetObject( &oTemp, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen) );
|
|
if ( m_oBuffer1.IsEOF() )
|
|
{
|
|
// TO DO: Error "End of file inside array"
|
|
}
|
|
Shift();
|
|
}
|
|
else if ( m_oBuffer1.IsCommand("<<") ) // Dictionary èëè Stream
|
|
{
|
|
Shift();
|
|
pObject->InitDict(m_pXref);
|
|
while ( !m_oBuffer1.IsCommand(">>") && !m_oBuffer1.IsEOF() )
|
|
{
|
|
if ( !m_oBuffer1.IsName() )
|
|
{
|
|
// TO DO: Error "Dictionary key must be a name object"
|
|
Shift();
|
|
}
|
|
else
|
|
{
|
|
char *sKey = CopyString( m_oBuffer1.GetName() );
|
|
Shift();
|
|
if ( m_oBuffer1.IsEOF() || m_oBuffer1.IsError() )
|
|
{
|
|
MemUtilsFree( sKey );
|
|
break;
|
|
}
|
|
pObject->DictAdd( sKey, GetObject( &oTemp, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen));
|
|
}
|
|
}
|
|
if ( m_oBuffer1.IsEOF() )
|
|
{
|
|
// TO DO: Error "End of file inside dictionary"
|
|
}
|
|
// Îáúåêòû Stream Objects íå äîïóñòèìû âíóòðè ïîòîêà èëè îáúåêòà òèïà Stream Objects
|
|
if ( m_bAllowStreams && m_oBuffer2.IsCommand("stream") )
|
|
{
|
|
if ( ( pStream = CreateStream(pObject, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen) ) )
|
|
{
|
|
pObject->InitStream( pStream );
|
|
}
|
|
else
|
|
{
|
|
pObject->Free();
|
|
pObject->InitError();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Shift();
|
|
}
|
|
}
|
|
else if ( m_oBuffer1.IsInt() ) // Ëèáî ññûëêà, ëèáî ÷èñëî
|
|
{
|
|
nNum = m_oBuffer1.GetInt();
|
|
Shift();
|
|
if ( m_oBuffer1.IsInt() && m_oBuffer2.IsCommand("R") )
|
|
{
|
|
pObject->InitRef( nNum, m_oBuffer1.GetInt());
|
|
Shift();
|
|
Shift();
|
|
}
|
|
else
|
|
{
|
|
pObject->InitInt(nNum);
|
|
}
|
|
}
|
|
else if ( m_oBuffer1.IsString() && sDecryptKey ) // ñòðîêà
|
|
{
|
|
StringExt *seTemp = m_oBuffer1.GetString();
|
|
StringExt *seRes = new StringExt();
|
|
oTemp.InitNull();
|
|
DecryptStream *pDecrypt = new DecryptStream(new MemoryStream( seTemp->GetBuffer(), 0, seTemp->GetLength(), &oTemp), sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen);
|
|
pDecrypt->Reset();
|
|
int nChar = 0;
|
|
while ( ( nChar = pDecrypt->GetChar() ) != EOF )
|
|
{
|
|
seRes->Append((char)nChar);
|
|
}
|
|
delete pDecrypt;
|
|
pObject->InitString(seRes);
|
|
Shift();
|
|
}
|
|
else // ïðîñòîé îáúåêò
|
|
{
|
|
m_oBuffer1.Copy(pObject);
|
|
Shift();
|
|
}
|
|
|
|
return pObject;
|
|
}
|
|
|
|
Stream *Parser::CreateStream(Object *pDict, unsigned char *sDecryptKey, CryptAlgorithm eEncryptAlgorithm, int nKeyLength, int nObjectNum, int nObjectGen)
|
|
{
|
|
Object oTemp;
|
|
unsigned int nLength, unEndPos;
|
|
|
|
m_pLexer->SkipToNextLine();
|
|
unsigned int unPos = m_pLexer->GetPos();
|
|
|
|
// Ñ÷èòûâàåì äëèíó
|
|
pDict->DictLookup("Length", &oTemp);
|
|
if ( oTemp.IsInt() )
|
|
{
|
|
nLength = (unsigned int)oTemp.GetInt();
|
|
oTemp.Free();
|
|
}
|
|
else
|
|
{
|
|
oTemp.Free();
|
|
unsigned int unEndPos = unPos;
|
|
|
|
while ( !m_oBuffer2.IsCommand("endstream") && !m_oBuffer2.IsEOF() )
|
|
{
|
|
unEndPos = m_pLexer->GetPos();
|
|
Shift();
|
|
}
|
|
|
|
nLength = unEndPos - unPos;
|
|
m_pLexer->SetPos( unPos );
|
|
|
|
// Îñòàâèì íà âñÿêèé ñëó÷àé çàãëóøêó
|
|
if ( nLength <= 0 )
|
|
nLength = 5000;
|
|
}
|
|
|
|
// Ìåíÿåì äëèíó, åñëè ôàéë ïîâðåæäåí
|
|
if ( m_pXref && m_pXref->GetStreamEnd( unPos, &unEndPos) )
|
|
{
|
|
nLength = unEndPos - unPos;
|
|
}
|
|
|
|
// Â ñèëüíî ïîâåðæäåííûõ ôàéëàõ PDF, âûñòàâëÿåì êîíåö ïîòîêà ñðàçó
|
|
// ïîñëå åãî íà÷àëà
|
|
if ( !m_pLexer->GetStream() )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
BaseStream *pBaseStream = m_pLexer->GetStream()->GetBaseStream();
|
|
|
|
// Ïðîïóñêàåì äàííûé ïîòîêà
|
|
m_pLexer->SetPos( unPos + nLength );
|
|
|
|
// Ïðîâåðÿåì 'endstream'
|
|
Shift(); // '>>'
|
|
Shift(); // 'endstream'
|
|
if ( m_oBuffer1.IsCommand("endstream") )
|
|
{
|
|
Shift();
|
|
}
|
|
else
|
|
{
|
|
// TO DO : Error "Missing 'endstream'"
|
|
|
|
// Çàïëàòêà äëÿ ïîâðåæäåííûõ ôàéëîâ:
|
|
nLength += 5000;
|
|
}
|
|
|
|
Stream *pStream = pBaseStream->MakeSubStream( unPos, TRUE, nLength, pDict );
|
|
|
|
// Decryption
|
|
if ( sDecryptKey )
|
|
{
|
|
pStream = new DecryptStream( pStream, sDecryptKey, eEncryptAlgorithm, nKeyLength, nObjectNum, nObjectGen);
|
|
}
|
|
|
|
// Filters
|
|
pStream = pStream->AddFilters( pDict );
|
|
|
|
return pStream;
|
|
}
|
|
|
|
void Parser::Shift()
|
|
{
|
|
if ( m_nInlineImage > 0 )
|
|
{
|
|
if ( m_nInlineImage < 2 )
|
|
{
|
|
++m_nInlineImage;
|
|
}
|
|
else
|
|
{
|
|
// Â ïîâðåæäåííîì ïîòîêå, åñëè 'ID' ïîÿâëÿåòñÿ â ñåðåäèíå ïîòîêà,
|
|
// íóæíî ñáðîñèòü ïàðàìåòðû
|
|
m_nInlineImage = 0;
|
|
}
|
|
}
|
|
else if ( m_oBuffer2.IsCommand("ID") )
|
|
{
|
|
m_pLexer->SkipChar(); // ïðîïóñêàåì ñèìâîë ïîñëå êîìàíäû 'ID'
|
|
m_nInlineImage = 1;
|
|
}
|
|
m_oBuffer1.Free();
|
|
m_oBuffer1 = m_oBuffer2;
|
|
if ( m_nInlineImage > 0 ) // íå áóôôåðèçèðóåì äàííûå Inline Image
|
|
m_oBuffer2.InitNull();
|
|
else
|
|
m_pLexer->GetObject( &m_oBuffer2 );
|
|
}
|