ooxml - add Word XML Document - fix bug #47039

read encrypted xml documents
This commit is contained in:
ElenaSubbotina
2020-11-09 11:41:12 +03:00
parent ececaee42b
commit 2be7dcb569
9 changed files with 232 additions and 6 deletions

View File

@ -51,6 +51,130 @@
int BinDocxRW::g_nCurFormatVersion = 0;
namespace BinDocxRW
{
class CPackageFile
{
public:
CPackageFile() {}
virtual ~CPackageFile() {}
bool unpackage(const std::wstring& sSrcFileName, const std::wstring& sDstPath)
{
m_sDestPath = sDstPath;
XmlUtils::CXmlLiteReader oReader;
if (!oReader.FromFile(sSrcFileName))
return false;
if (!oReader.ReadNextNode())
return false;
std::wstring sName = oReader.GetName();
if (L"pkg:package" != sName)
return false;
int nDepth = oReader.GetDepth();
while (oReader.ReadNextSiblingNode(nDepth))
{
sName = oReader.GetName();
if (L"pkg:part" == sName)
{
read_package_part(oReader);
}
}
m_oContentTypes.Write(m_sDestPath);
return true;
}
private:
std::wstring m_sDestPath;
OOX::CContentTypes m_oContentTypes;
void read_package_part(XmlUtils::CXmlLiteReader &oReader)
{
nullable_int padding;
nullable_string compression;
nullable_string contentType;
nullable_string name;
WritingElement_ReadAttributes_Start(oReader)
WritingElement_ReadAttributes_Read_if(oReader, L"pkg:name", name)
WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:contentType", contentType)
WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:padding", padding)
WritingElement_ReadAttributes_Read_else_if(oReader, L"pkg:compression", compression)
WritingElement_ReadAttributes_End(oReader)
if (name.IsInit() == false) return;
if (contentType.IsInit())
{
m_oContentTypes.Registration(*contentType, L"", *name);
}
int nDepth = oReader.GetDepth();
while (oReader.ReadNextSiblingNode(nDepth))
{
std::wstring sName = oReader.GetName();
if (L"pkg:xmlData" == sName)
{
std::wstring data = oReader.GetInnerXml();
WriteXmlFile(*name, data);
}
if (L"pkg:binaryData" == sName)
{
std::string data = oReader.GetText2A();
WriteBinaryFile(*name, data, compression.IsInit() ? compression.get() : L"");
}
}
}
void WriteXmlFile(const std::wstring & name, std::wstring & data)
{
if (name.empty()) return;
OOX::CPath path(m_sDestPath + name);
NSDirectory::CreateDirectories(path.GetDirectory());
NSFile::CFileBinary file;
if (file.CreateFileW(path.GetPath()))
{
file.WriteStringUTF8(data);
file.CloseFile();
}
}
void WriteBinaryFile(const std::wstring & name, std::string & data, const std::wstring & compression)
{
if (name.empty()) return;
OOX::CPath path(m_sDestPath + name);
NSDirectory::CreateDirectories(path.GetDirectory());
NSFile::CFileBinary file;
if (file.CreateFileW(path.GetPath()))
{
BYTE* pDstBuffer = NULL;
int dstLen = Base64::Base64DecodeGetRequiredLength((int)data.size());
pDstBuffer = new BYTE[dstLen];
if (pDstBuffer)
{
Base64::Base64Decode(data.c_str(), (int)data.size(), pDstBuffer, &dstLen);
file.WriteFile(pDstBuffer, (DWORD)dstLen);
file.CloseFile();
delete []pDstBuffer;
}
}
}
};
}
BinDocxRW::CDocxSerializer::CDocxSerializer()
{
m_pParamsWriter = NULL;
@ -148,7 +272,6 @@ bool BinDocxRW::CDocxSerializer::saveToFile(const std::wstring& sSrcFileName, co
RELEASEOBJECT(pFontPicker);
return true;
}
bool BinDocxRW::CDocxSerializer::CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath)
{
bool res = true;
@ -481,3 +604,10 @@ void BinDocxRW::CDocxSerializer::setSaveChartAsImg(bool bSaveChartAsImg)
{
m_bSaveChartAsImg = bSaveChartAsImg;
}
bool BinDocxRW::CDocxSerializer::unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath)
{
BinDocxRW::CPackageFile file;
return file.unpackage(sSrcFileName, sDstPath);
}

View File

@ -63,6 +63,8 @@ namespace BinDocxRW
bool loadFromFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sThemePath, const std::wstring& sMediaPath, const std::wstring& sEmbedPath);
bool saveToFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sXMLOptions, const std::wstring& sTempPath);
bool unpackageFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath);
bool CreateDocxFolders(std::wstring strDirectory, std::wstring& sThemePath, std::wstring& sMediaPath, std::wstring& sEmbedPath);

View File

@ -75,8 +75,8 @@ namespace OOX
if ( oReader.IsEmptyNode() )
return;
int nStylesDepth = oReader.GetDepth();
while ( oReader.ReadNextSiblingNode( nStylesDepth ) )
int nDepth = oReader.GetDepth();
while ( oReader.ReadNextSiblingNode(nDepth) )
{
std::wstring sName = oReader.GetName();

View File

@ -787,6 +787,7 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char* pBuffer,int dw
const char *docxFormatLine = "xmlns:w=\"http://schemas.microsoft.com/office/word/2003/wordml\"";
const char *xlsxFormatLine = "xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"";
const char *packageFormatLine = "xmlns:pkg=\"http://schemas.microsoft.com/office/2006/xmlPackage\"";
if (std::string::npos != xml_string.find(docxFormatLine))
{
@ -796,7 +797,10 @@ bool COfficeFileFormatChecker::isOOXFlatFormatFile(unsigned char* pBuffer,int dw
{
nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT;
}
else if (std::string::npos != xml_string.find(packageFormatLine))
{
nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE;
}
if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) return true;
return false;

View File

@ -52,6 +52,7 @@
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0010
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0011
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0012
#define AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0013
#define AVS_OFFICESTUDIO_FILE_PRESENTATION 0x0080
#define AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0001

View File

@ -131,6 +131,67 @@ namespace NExtractTools
}
return hRes;
}
_UINT32 package2docx(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
{
std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked");
NSDirectory::CreateDirectory(sResultDocxDir);
_UINT32 nRes = package2docx_dir(sFrom, sResultDocxDir, sTemp, params);
if (SUCCEEDED_X2T(nRes))
{
COfficeUtils oCOfficeUtils(NULL);
nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDocxDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT;
}
return nRes;
}
_UINT32 package2doct(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
{
std::wstring sResultDoctDir = sTemp + FILE_SEPARATOR_STR + _T("doct_unpacked");
std::wstring sResultDoctFileEditor = sResultDoctDir + FILE_SEPARATOR_STR + _T("Editor.bin");
NSDirectory::CreateDirectory(sResultDoctDir);
_UINT32 nRes = package2doct_bin(sFrom, sResultDoctFileEditor, sTemp, params);
if (SUCCEEDED_X2T(nRes))
{
COfficeUtils oCOfficeUtils(NULL);
nRes = (S_OK == oCOfficeUtils.CompressFileOrDirectory(sResultDoctDir, sTo)) ? nRes : AVS_FILEUTILS_ERROR_CONVERT;
}
return nRes;
}
_UINT32 package2doct_bin(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
{
std::wstring sResultDocxDir = sTemp + FILE_SEPARATOR_STR + _T("docx_unpacked");
NSDirectory::CreateDirectory(sResultDocxDir);
_UINT32 nRes = package2docx_dir(sFrom, sResultDocxDir, sTemp, params);
if (SUCCEEDED_X2T(nRes))
{
BinDocxRW::CDocxSerializer m_oCDocxSerializer;
m_oCDocxSerializer.setIsNoBase64(params.getIsNoBase64());
m_oCDocxSerializer.setFontDir(params.getFontPath());
nRes = m_oCDocxSerializer.saveToFile(sTo, sResultDocxDir, params.getXmlOptions(), sTemp) ? 0 : AVS_FILEUTILS_ERROR_CONVERT;
}
return nRes;
}
_UINT32 package2docx_dir(const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
{
BinDocxRW::CDocxSerializer m_oCDocxSerializer;
_UINT32 nRes = m_oCDocxSerializer.unpackageFile(sFrom, sTo) ? 0 : AVS_FILEUTILS_ERROR_CONVERT;
return nRes;
}
// docxflat -> bin
_UINT32 docxflat2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params)
{
@ -2740,6 +2801,19 @@ namespace NExtractTools
{
return pptx2pptt_bin(sResultDecryptFile, sTo, sTemp,params);
}break;
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT:
{
return docxflat2doct_bin(sResultDecryptFile, sTo, sTemp, params);
}break;
case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT:
{
const std::wstring & sXmlOptions = params.getXmlOptions();
return xlsxflat2xlst_bin(sResultDecryptFile, sTo, sTemp, params);
}break;
case AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE:
{
return package2doct_bin(sResultDecryptFile, sTo, sTemp, params);
}break;
}
}
return AVS_FILEUTILS_ERROR_CONVERT;

View File

@ -59,6 +59,11 @@ namespace NExtractTools
_UINT32 docxflat2doct (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 docxflat2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 package2docx (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 package2docx_dir (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 package2doct (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 package2doct_bin (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 dotm2docm (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);
_UINT32 dotm2docm_dir (const std::wstring &sFrom, const std::wstring &sTo, InputParams& params);
_UINT32 dotx2docx (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params);

View File

@ -131,9 +131,15 @@ namespace NExtractTools
}break;
case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT:
{
if (0 == sExt2.compare(_T(".doct"))) res = TCD_DOCXFLAT2DOCT;
else if (0 == sExt2.compare(_T(".bin"))) res = TCD_DOCXFLAT2DOCT_BIN;
if (0 == sExt2.compare(_T(".doct"))) res = TCD_PKG2DOCT;
else if (0 == sExt2.compare(_T(".bin"))) res = TCD_PKG2DOCT_BIN;
else if (0 == sExt2.compare(_T(".docx"))) res = TCD_PKG2DOCX;
}break;
case AVS_OFFICESTUDIO_FILE_DOCUMENT_PACKAGE:
{
if (0 == sExt2.compare(_T(".doct"))) res = TCD_DOCXFLAT2DOCT;
else if (0 == sExt2.compare(_T(".bin"))) res = TCD_DOCXFLAT2DOCT_BIN;
}break;
case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX_FLAT:
{
if (0 == sExt2.compare(_T(".xlst"))) res = TCD_XLSXFLAT2XLST;

View File

@ -75,6 +75,10 @@ namespace NExtractTools
TCD_DOCXFLAT2DOCT,
TCD_DOCXFLAT2DOCT_BIN,
TCD_PKG2DOCX,
TCD_PKG2DOCT,
TCD_PKG2DOCT_BIN,
TCD_XLSXFLAT2XLST,
TCD_XLSXFLAT2XLST_BIN,