mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-06-27 07:24:52 +08:00
Compare commits
46 Commits
feature/bi
...
v9.4.0.81
| Author | SHA1 | Date | |
|---|---|---|---|
| 764a8e4cd9 | |||
| 6a45740f98 | |||
| dfe6d300d8 | |||
| cce7058d46 | |||
| 71a8a22d2e | |||
| 7c7ebd5f2a | |||
| 7890f5b87f | |||
| 69a066fac9 | |||
| 1a94960abf | |||
| 00bee83d0e | |||
| 37d83faffd | |||
| 5b15d9b77b | |||
| c5a040c807 | |||
| bb9e3a2a7e | |||
| e2c560d5ad | |||
| 2ed3521355 | |||
| 1c1947459d | |||
| 29b2b2e086 | |||
| 2761614b8d | |||
| 2deb6b8c42 | |||
| 59e4d02f01 | |||
| 99b31a46f7 | |||
| 5a0bc5a19d | |||
| 38bbe37f40 | |||
| eb4c5cfc2a | |||
| 6262048e75 | |||
| 7877f542b3 | |||
| f00581fd1d | |||
| bd3dd15a4f | |||
| a796e92fe1 | |||
| 3d7381dc68 | |||
| e33e3d6b42 | |||
| c03fd25b6d | |||
| c7c98d3f69 | |||
| d9d7ffef26 | |||
| b0efeafd27 | |||
| 8a3a922dba | |||
| b78bcb10dc | |||
| 653ff24c0e | |||
| a62f97627b | |||
| 612c26cf6c | |||
| 2873418d74 | |||
| 77346270a4 | |||
| 5f39acbe51 | |||
| 6badba384c | |||
| c96df4e62e |
36
Common/3dParty/boost/patches/mpl_integral_wrapper.patch
Normal file
36
Common/3dParty/boost/patches/mpl_integral_wrapper.patch
Normal file
@ -0,0 +1,36 @@
|
||||
<<<<<<<
|
||||
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 243)
|
||||
private:
|
||||
BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, next_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)));
|
||||
BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, prior_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)));
|
||||
public:
|
||||
typedef AUX_WRAPPER_INST(next_value) next;
|
||||
typedef AUX_WRAPPER_INST(prior_value) prior;
|
||||
#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \
|
||||
|| BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \
|
||||
|| (BOOST_WORKAROUND(__HP_aCC, <= 53800) && (BOOST_WORKAROUND(__hpxstd98, != 1)))
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)) ) next;
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)) ) prior;
|
||||
#else
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next;
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
|
||||
#endif
|
||||
=======
|
||||
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 243) \
|
||||
|| defined(__clang__)
|
||||
private:
|
||||
BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, next_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)));
|
||||
BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, prior_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)));
|
||||
public:
|
||||
typedef AUX_WRAPPER_INST(next_value) next;
|
||||
typedef AUX_WRAPPER_INST(prior_value) prior;
|
||||
#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \
|
||||
|| BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \
|
||||
|| (BOOST_WORKAROUND(__HP_aCC, <= 53800) && (BOOST_WORKAROUND(__hpxstd98, != 1)))
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)) ) next;
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)) ) prior;
|
||||
#else
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next;
|
||||
typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
|
||||
#endif
|
||||
>>>>>>>
|
||||
@ -1578,25 +1578,31 @@ namespace NSFile
|
||||
std::wstring CFileBinary::CreateTempFileWithUniqueName(const std::wstring& strFolderPathRoot, const std::wstring& Prefix)
|
||||
{
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64)
|
||||
wchar_t pBuffer[MAX_PATH + 1];
|
||||
::GetTempFileNameW(strFolderPathRoot.c_str(), Prefix.c_str(), 0, pBuffer);
|
||||
std::wstring sRet(pBuffer);
|
||||
return sRet;
|
||||
wchar_t pBuffer[MAX_PATH + 1] = {0};
|
||||
if (0 == ::GetTempFileNameW(strFolderPathRoot.c_str(), Prefix.c_str(), 0, pBuffer))
|
||||
return std::wstring();
|
||||
return std::wstring(pBuffer);
|
||||
#else
|
||||
char pcRes[MAX_PATH];
|
||||
BYTE* pData = (BYTE*)pcRes;
|
||||
|
||||
std::wstring sPrefix = strFolderPathRoot + L"/" + Prefix + L"_XXXXXX";
|
||||
LONG lLen = 0;
|
||||
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sPrefix.c_str(), (LONG)sPrefix.length(), pData, lLen);
|
||||
pcRes[lLen] = '\0';
|
||||
|
||||
int res = mkstemp(pcRes);
|
||||
LONG lLen = 0;
|
||||
BYTE* pcRes = NULL;
|
||||
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sPrefix.c_str(), (LONG)sPrefix.length(), pcRes, lLen);
|
||||
|
||||
if (lLen <= 0)
|
||||
{
|
||||
delete[] pcRes;
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
int res = mkstemp((char*)pcRes);
|
||||
if (-1 != res)
|
||||
close(res);
|
||||
|
||||
std::string sRes = pcRes;
|
||||
return NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sRes.c_str(), sRes.length());
|
||||
std::wstring sResult = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pcRes, (LONG)lLen);
|
||||
|
||||
delete[] pcRes;
|
||||
return sResult;
|
||||
#endif
|
||||
}
|
||||
bool CFileBinary::OpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder, wchar_t* wsName)
|
||||
|
||||
@ -210,6 +210,7 @@ namespace NSOnlineOfficeBinToPdf
|
||||
oRenderer.CreateFromBgraFrame(&oFrame);
|
||||
oRenderer.SetTileImageDpi(96.0);
|
||||
oRenderer.SetSwapRGB(false);
|
||||
oRenderer.CommandLong(c_nPenWidth0As1px, 1);
|
||||
|
||||
this->m_pRenderer = &oRenderer;
|
||||
BYTE* pBufferPage = oInfo.arSizes[nPageIndex].data;
|
||||
|
||||
@ -897,6 +897,7 @@ CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* CAnnotFieldInfo::CWidgetAnn
|
||||
CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetTextWidgetPr() { return m_pTextPr; }
|
||||
CAnnotFieldInfo::CWidgetAnnotPr::CChoiceWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetChoiceWidgetPr() { return m_pChoicePr; }
|
||||
CAnnotFieldInfo::CWidgetAnnotPr::CSignatureWidgetPr* CAnnotFieldInfo::CWidgetAnnotPr::GetSignatureWidgetPr() { return m_pSignaturePr; }
|
||||
void CAnnotFieldInfo::CWidgetAnnotPr::SetFontName(const std::wstring& sName) { m_wsFN = sName; }
|
||||
CAnnotFieldInfo::CWidgetAnnotPr::CWidgetAnnotPr(BYTE nType)
|
||||
{
|
||||
m_pButtonPr = NULL;
|
||||
|
||||
@ -203,6 +203,8 @@ public:
|
||||
const std::vector<double>& GetBG();
|
||||
const std::vector<CActionFieldPr*>& GetActions();
|
||||
|
||||
void SetFontName(const std::wstring& sName);
|
||||
|
||||
CButtonWidgetPr* GetButtonWidgetPr();
|
||||
CTextWidgetPr* GetTextWidgetPr();
|
||||
CChoiceWidgetPr* GetChoiceWidgetPr();
|
||||
|
||||
@ -233,20 +233,98 @@ namespace NSHtmlRenderer
|
||||
NSWasm::CHChar* pLastChar = m_oLine.GetTail();
|
||||
if (dOffsetX > (pLastChar->width + 0.5))
|
||||
{
|
||||
// insert space. Our space will not be a regular space. But a specific one
|
||||
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
|
||||
pLastChar = &m_oLine.m_pChars[m_oLine.m_lCharsTail - 2];
|
||||
pSpaceChar->x = pLastChar->width;
|
||||
pSpaceChar->width = dOffsetX - pLastChar->width;
|
||||
pSpaceChar->unicode = 0xFFFF;
|
||||
dOffsetX -= pLastChar->width;
|
||||
if (pLastChar->unicode == 32 || pLastChar->unicode == 9)
|
||||
{
|
||||
pLastChar->width = dOffsetX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// insert space. Our space will not be a regular space. But a specific one
|
||||
NSWasm::CHChar* pSpaceChar = m_oLine.AddTail();
|
||||
pLastChar = &m_oLine.m_pChars[m_oLine.m_lCharsTail - 2];
|
||||
pSpaceChar->x = pLastChar->width;
|
||||
pSpaceChar->width = dOffsetX - pLastChar->width;
|
||||
pSpaceChar->unicode = 0xFFFF;
|
||||
dOffsetX -= pLastChar->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// letter is shifted left relative to previous letter
|
||||
// we react to this situation simply - just start a new line,
|
||||
// after dumping the old one
|
||||
// check if new glyph lands inside a synthetic space (0xFFFF) in current line
|
||||
double sx = _x1 - m_oLine.m_dX;
|
||||
double sy = _y1 - m_oLine.m_dY;
|
||||
double newGlyphOffset = sx * m_oLine.m_ex + sy * m_oLine.m_ey;
|
||||
|
||||
// walk through chars accumulating offset to find which char we hit
|
||||
double charOffset = 0;
|
||||
LONG nCount = m_oLine.GetCountChars();
|
||||
LONG nSplitIndex = -1;
|
||||
for (LONG i = 0; i < nCount; ++i)
|
||||
{
|
||||
NSWasm::CHChar* pCh = &m_oLine.m_pChars[i];
|
||||
if (i > 0)
|
||||
charOffset += pCh->x; // x here is offset from previous char
|
||||
if (pCh->unicode == 0xFFFF &&
|
||||
newGlyphOffset >= charOffset &&
|
||||
newGlyphOffset < charOffset + pCh->width)
|
||||
{
|
||||
nSplitIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nSplitIndex >= 0)
|
||||
{
|
||||
NSWasm::CHLine oSaved;
|
||||
oSaved = m_oLine;
|
||||
|
||||
// --- Dump head: chars [0 .. nSplitIndex - 1] ---
|
||||
m_oLine.m_lCharsTail = nSplitIndex; // truncate before the 0xFFFF
|
||||
DumpLine(); // clears m_oLine
|
||||
|
||||
// --- Dump tail: chars [nSplitIndex + 1 .. nCount - 1] ---
|
||||
LONG nTailStart = nSplitIndex + 1;
|
||||
LONG nTailCount = nCount - nTailStart;
|
||||
if (nTailCount > 0)
|
||||
{
|
||||
// Reconstruct baseline origin for the tail.
|
||||
// Walk offsets up to nTailStart to find its position along baseline.
|
||||
double tailOffset = 0;
|
||||
for (LONG i = 1; i <= nTailStart; ++i)
|
||||
tailOffset += oSaved.m_pChars[i].x;
|
||||
|
||||
m_oLine.m_bIsConstX = oSaved.m_bIsConstX;
|
||||
m_oLine.m_dK = oSaved.m_dK;
|
||||
m_oLine.m_dB = oSaved.m_dB;
|
||||
m_oLine.m_ex = oSaved.m_ex;
|
||||
m_oLine.m_ey = oSaved.m_ey;
|
||||
m_oLine.m_dAscent = oSaved.m_dAscent;
|
||||
m_oLine.m_dDescent = oSaved.m_dDescent;
|
||||
m_oLine.m_bIsSetUpTransform = oSaved.m_bIsSetUpTransform;
|
||||
m_oLine.m_sx = oSaved.m_sx;
|
||||
m_oLine.m_sy = oSaved.m_sy;
|
||||
m_oLine.m_shx = oSaved.m_shx;
|
||||
m_oLine.m_shy = oSaved.m_shy;
|
||||
|
||||
// Origin of tail shifted along baseline
|
||||
m_oLine.m_dX = oSaved.m_dX + tailOffset * oSaved.m_ex;
|
||||
m_oLine.m_dY = oSaved.m_dY + tailOffset * oSaved.m_ey;
|
||||
m_oLine.m_dEndX = m_oLine.m_dX;
|
||||
m_oLine.m_dEndY = m_oLine.m_dY;
|
||||
|
||||
// Copy tail chars; first tail char has x=0 (it's now the line origin)
|
||||
for (LONG i = 0; i < nTailCount; ++i)
|
||||
{
|
||||
NSWasm::CHChar* pDst = m_oLine.AddTail();
|
||||
*pDst = oSaved.m_pChars[nTailStart + i];
|
||||
if (i == 0)
|
||||
pDst->x = 0; // first char offset is always 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DumpLine();
|
||||
|
||||
m_oLine.m_bIsConstX = _isConstX;
|
||||
|
||||
@ -424,8 +424,14 @@ namespace NSWasm
|
||||
m_dX = oLine.m_dX;
|
||||
m_dY = oLine.m_dY;
|
||||
|
||||
m_dEndX = oLine.m_dEndX;
|
||||
m_dEndY = oLine.m_dEndY;
|
||||
|
||||
m_dK = oLine.m_dK;
|
||||
m_dB = oLine.m_dB;
|
||||
m_ex = oLine.m_ex;
|
||||
m_ey = oLine.m_ey;
|
||||
m_bIsConstX = oLine.m_bIsConstX;
|
||||
|
||||
m_lSizeChars = oLine.m_lSizeChars;
|
||||
m_lCharsTail = oLine.m_lCharsTail;
|
||||
|
||||
@ -30,6 +30,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test utility. NOT used in production builds.
|
||||
*
|
||||
* This code is intended solely for local debugging and verification
|
||||
* of internal components by developers. Security concerns
|
||||
* (error handling, input validation, protection against race conditions,
|
||||
* buffer overflows, etc.) are intentionally not addressed in this file
|
||||
* and are not applicable.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
@ -367,7 +367,8 @@ namespace NSDocxRenderer
|
||||
bForcedBold,
|
||||
m_bUseDefaultFont,
|
||||
m_bWriteStyleRaw,
|
||||
m_bCollectMetaInfo
|
||||
m_bCollectMetaInfo,
|
||||
m_bFontSubstitution
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -2544,7 +2544,7 @@ void XlsConverter::convert(XLS::Obj * obj)
|
||||
std::wstring objectId_bin = xlsx_context->get_mediaitems().add_control_activeX(target_bin);
|
||||
|
||||
NSFile::CFileBinary file;
|
||||
if(xls_global_info->controls_data.second >= obj->pictFmla.lPosInCtlStm + obj->pictFmla.cbBufInCtlStm)
|
||||
if (obj->pictFmla.lPosInCtlStm <= xls_global_info->controls_data.second && obj->pictFmla.cbBufInCtlStm <= xls_global_info->controls_data.second - obj->pictFmla.lPosInCtlStm)
|
||||
{
|
||||
if ( file.CreateFileW(xlsx_context->get_mediaitems().activeX_path() + target_bin) )
|
||||
{
|
||||
|
||||
@ -140,6 +140,8 @@ void AutoFilter::readFields(CFRecord& record)
|
||||
if (record.getRdPtr() - pos_record < size)
|
||||
{
|
||||
int sz = size - (record.getRdPtr() - pos_record);
|
||||
sz = (std::min)(sz, (int)(record.getDataSize() - record.getRdPtr()));
|
||||
|
||||
char *dd = new char [sz];
|
||||
|
||||
memcpy(dd, record.getCurData<char>(), sz);
|
||||
|
||||
@ -54,7 +54,7 @@ void RichTextStream::readFields(CFRecord& record)
|
||||
{
|
||||
record >> frtHeader >> dwCheckSum >> cb;
|
||||
|
||||
if (cb > 0 &&cb < 0xffff)
|
||||
if (cb > 0 && cb < 0xffff && cb <= record.getDataSize() - record.getRdPtr())
|
||||
{
|
||||
rgb = std::string(record.getCurData<char>(), cb);
|
||||
record.skipNunBytes(cb);
|
||||
|
||||
@ -44,7 +44,7 @@ void SXViewEx::readFields(CFRecord& record)
|
||||
{
|
||||
record >> frtHeaderOld >> csxth >> csxpi >> csxvdtex >> cbFuture;
|
||||
|
||||
if (cbFuture)
|
||||
if (cbFuture > 0 && cbFuture <= record.getDataSize() - record.getRdPtr())
|
||||
rgbFuture = std::string(record.getCurData<char>(), cbFuture);
|
||||
|
||||
record.skipNunBytes(record.getDataSize() - record.getRdPtr());
|
||||
|
||||
@ -58,7 +58,7 @@ void TextPropsStream::readFields(CFRecord& record)
|
||||
_UINT32 cb=0;
|
||||
record >> cb;
|
||||
|
||||
if (cb > 0)
|
||||
if (cb > 0 && cb <= record.getDataSize() - record.getRdPtr())
|
||||
{
|
||||
xml_ = std::string( record.getCurData<char>(), cb);
|
||||
record.skipNunBytes(cb);
|
||||
|
||||
@ -782,6 +782,8 @@ void AnyString::ReadComplexData(IBinaryReader* reader)
|
||||
}
|
||||
void AnyString::ReadComplexData(XLS::CFRecord& record)
|
||||
{
|
||||
if (op > record.getDataSize() - record.getRdPtr()) return;
|
||||
|
||||
std::wstring tmp;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
tmp = std::wstring(record.getCurData<wchar_t>(), op / 2);
|
||||
@ -1029,6 +1031,8 @@ void XmlString::ReadComplexData(IBinaryReader* reader)
|
||||
}
|
||||
void XmlString::ReadComplexData(XLS::CFRecord& record)
|
||||
{
|
||||
if (op > record.getDataSize() - record.getRdPtr()) return;
|
||||
|
||||
boost::shared_array<char> buffer(new char[op]);
|
||||
memcpy(buffer.get(), record.getCurData<char>(), op);
|
||||
|
||||
@ -1044,7 +1048,7 @@ void MetroBlob::ReadComplexData(IBinaryReader* reader)
|
||||
}
|
||||
void MetroBlob::ReadComplexData(XLS::CFRecord& record)
|
||||
{
|
||||
int pos = record.getRdPtr();
|
||||
if (op > record.getDataSize() - record.getRdPtr()) return;
|
||||
|
||||
data = std::make_pair(boost::shared_array<unsigned char>(new unsigned char[op]), op);
|
||||
|
||||
|
||||
@ -150,16 +150,16 @@ int XLUnicodeRichExtendedString::serialize (std::wostream & _stream)
|
||||
}
|
||||
int XLUnicodeRichExtendedString::serialize_rPr (std::wostream & _stream, int iFmt)
|
||||
{
|
||||
if (!pGlobalWorkbookInfoPtr) return 0;
|
||||
if (!pGlobalWorkbookInfoPtr) return 0;
|
||||
|
||||
int sz = pGlobalWorkbookInfoPtr->m_arFonts.size();
|
||||
if (iFmt -1 > sz || iFmt < 1) return 0;
|
||||
if (iFmt > sz || iFmt < 1) return 0;
|
||||
|
||||
CP_XML_WRITER(_stream)
|
||||
{
|
||||
CP_XML_NODE(L"rPr")
|
||||
{
|
||||
Font * font = dynamic_cast<Font*>(pGlobalWorkbookInfoPtr->m_arFonts[iFmt-1].get());
|
||||
Font * font = dynamic_cast<Font*>(pGlobalWorkbookInfoPtr->m_arFonts[iFmt - 1].get());
|
||||
|
||||
if (font) font->serialize_properties(CP_XML_STREAM(), true);
|
||||
}
|
||||
|
||||
@ -126,12 +126,15 @@ const bool ATTACHEDLABEL::loadContent(BinProcessor& proc)
|
||||
elements_.pop_back();
|
||||
|
||||
ObjectLink *o_l = dynamic_cast<ObjectLink*>(m_ObjectLink.get());
|
||||
|
||||
m_iLinkObject = o_l->wLinkObj;
|
||||
|
||||
Pos * pos = dynamic_cast<Pos*>(m_Pos.get());
|
||||
if (pos)
|
||||
pos->m_iLinkObject = m_iLinkObject;
|
||||
if (o_l)
|
||||
{
|
||||
m_iLinkObject = o_l->wLinkObj;
|
||||
|
||||
Pos* pos = dynamic_cast<Pos*>(m_Pos.get());
|
||||
if (pos)
|
||||
pos->m_iLinkObject = m_iLinkObject;
|
||||
}
|
||||
}
|
||||
|
||||
if (proc.optional<DataLabExtContents>())
|
||||
@ -393,12 +396,12 @@ int ATTACHEDLABEL::serialize(std::wostream & _stream, bool isPosition)
|
||||
|
||||
int ATTACHEDLABEL::serialize_rPr (std::wostream & _stream, int iFnt, bool rtl, bool defRPr)
|
||||
{
|
||||
if (!pGlobalWorkbookInfoPtr) return 0;
|
||||
if (!pGlobalWorkbookInfoPtr) return 0;
|
||||
|
||||
int sz = pGlobalWorkbookInfoPtr->m_arFonts.size();
|
||||
if (iFnt - 1 > sz || iFnt < 1) return 0;
|
||||
if (iFnt > sz || iFnt < 1) return 0;
|
||||
|
||||
Font * font = dynamic_cast<Font*>(pGlobalWorkbookInfoPtr->m_arFonts[iFnt -1].get());
|
||||
Font * font = dynamic_cast<Font*>(pGlobalWorkbookInfoPtr->m_arFonts[iFnt - 1].get());
|
||||
|
||||
Text * text_props = dynamic_cast<Text*>(m_TextProperties.get());
|
||||
|
||||
|
||||
@ -128,7 +128,9 @@ void AXISPARENT::concatinate_second (BaseObjectPtr & addit)
|
||||
for (size_t i = 0; i < second->m_arCRT.size(); i++)
|
||||
{
|
||||
CRT* crt = dynamic_cast<CRT*>(second->m_arCRT[i].get());
|
||||
crt->m_indAXISPARENT = 1;
|
||||
|
||||
if (crt)
|
||||
crt->m_indAXISPARENT = 1;
|
||||
|
||||
m_arCRT.push_back(second->m_arCRT[i]);
|
||||
}
|
||||
|
||||
@ -323,13 +323,15 @@ int SUPBOOK::serialize_book(std::wostream & strm)
|
||||
for (size_t k = j; k < m_arXCT[i].m_arCRN.size(); k++)
|
||||
{
|
||||
cell = dynamic_cast<CRN*>(m_arXCT[i].m_arCRN[k].get());
|
||||
if (!cell) continue;
|
||||
|
||||
if (cell->row != current_row)
|
||||
{
|
||||
j = k - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned char col = cell->colFirst, v = 0; col <= cell->colLast; col++, v++)
|
||||
for (unsigned char col = cell->colFirst, v = 0; col <= cell->colLast && v < cell->crnOper.size(); col++, v++)
|
||||
{
|
||||
CP_XML_NODE(L"cell")
|
||||
{
|
||||
|
||||
@ -509,7 +509,7 @@ void ChartSheetSubstream::recalc(CHARTFORMATS* charts)
|
||||
|
||||
iCrt = serCrt->id;
|
||||
|
||||
while ((parent0->m_arCRT.size() <= iCrt) && (ind_AXIS < charts->m_arAXISPARENT.size()) && (charts->m_arAXISPARENT.size() > 1))
|
||||
while ((parent0->m_arCRT.size() <= iCrt) && (ind_AXIS + 1 < charts->m_arAXISPARENT.size()) && (charts->m_arAXISPARENT.size() > 1))
|
||||
{
|
||||
parent0 = dynamic_cast<AXISPARENT*>(charts->m_arAXISPARENT[++ind_AXIS].get());
|
||||
|
||||
|
||||
@ -13,7 +13,8 @@ PWD_ROOT_DIR = $$PWD
|
||||
include($$CORE_ROOT_DIR/Common/base.pri)
|
||||
include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri)
|
||||
|
||||
DEFINES += OFD_USE_DYNAMIC_LIBRARY
|
||||
DEFINES += OFD_USE_DYNAMIC_LIBRARY \
|
||||
CRYPTOPP_DISABLE_ASM
|
||||
|
||||
ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, PdfFile)
|
||||
|
||||
|
||||
165
OOXML/Base/Rand.h
Normal file
165
OOXML/Base/Rand.h
Normal file
@ -0,0 +1,165 @@
|
||||
#ifndef SECURE_RANDOM_BYTES_H
|
||||
#define SECURE_RANDOM_BYTES_H
|
||||
|
||||
#include <random>
|
||||
#include <mutex>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(WIN_XP_OR_VISTA)
|
||||
|
||||
// RtlGenRandom (a.k.a. SystemFunction036 in advapi32.dll).
|
||||
// Available since Windows XP, cryptographically secure,
|
||||
// does not open key containers — stable under load.
|
||||
extern "C" BOOLEAN NTAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength);
|
||||
#pragma comment(lib, "advapi32.lib")
|
||||
|
||||
#else
|
||||
|
||||
#include <bcrypt.h>
|
||||
#pragma comment(lib, "bcrypt.lib")
|
||||
#endif
|
||||
|
||||
#elif defined(_MAC)
|
||||
|
||||
#include <Security/Security.h>
|
||||
|
||||
#elif defined(_LINUX)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
// Fallback syscall numbers for systems where SYS_getrandom is not in headers.
|
||||
// getrandom() syscall added in Linux 3.17 (October 2014).
|
||||
|
||||
#ifndef SYS_getrandom
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#define SYS_getrandom 318
|
||||
#elif defined(__i386__)
|
||||
#define SYS_getrandom 355
|
||||
#elif defined(__aarch64__)
|
||||
#define SYS_getrandom 278
|
||||
#elif defined(__arm__)
|
||||
#define SYS_getrandom 384
|
||||
#elif defined(__powerpc64__)
|
||||
#define SYS_getrandom 359
|
||||
#elif defined(__riscv)
|
||||
#define SYS_getrandom 278
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Fills `buf` with `len` cryptographically secure random bytes.
|
||||
// Returns true on success, false if every available source failed.
|
||||
static bool SecureRandomBytes(unsigned char* buf, size_t len)
|
||||
{
|
||||
if (len == 0)
|
||||
return true;
|
||||
if (buf == nullptr)
|
||||
return false;
|
||||
|
||||
size_t filled = 0;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#if defined(WIN_XP_OR_VISTA)
|
||||
while (filled < len)
|
||||
{
|
||||
ULONG chunk = (len - filled > 0xFFFFFF00u) ? 0xFFFFFF00u : static_cast<ULONG>(len - filled);
|
||||
if (!::SystemFunction036(buf + filled, chunk))
|
||||
break;
|
||||
filled += chunk;
|
||||
}
|
||||
if (filled == len)
|
||||
return true;
|
||||
#else
|
||||
while (filled < len)
|
||||
{
|
||||
ULONG chunk = (len - filled > 0xFFFFFF00u) ? 0xFFFFFF00u : static_cast<ULONG>(len - filled);
|
||||
NTSTATUS status = ::BCryptGenRandom(nullptr, buf + filled, chunk, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||
if (status != 0) // STATUS_SUCCESS
|
||||
break;
|
||||
filled += chunk;
|
||||
}
|
||||
if (filled == len)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#elif defined(_MAC)
|
||||
if (::SecRandomCopyBytes(kSecRandomDefault, len, buf) == errSecSuccess)
|
||||
return true;
|
||||
|
||||
#elif defined(__ANDROID__) || defined(__linux__)
|
||||
// ===== Linux / Android =====
|
||||
// Direct syscall — does not depend on glibc version or headers.
|
||||
// On kernels older than 3.17 syscall returns ENOSYS and we fall through.
|
||||
#ifdef SYS_getrandom
|
||||
while (filled < len) {
|
||||
size_t chunk = (len - filled > 256) ? 256 : (len - filled);
|
||||
long ret = ::syscall(SYS_getrandom, buf + filled, chunk, 0);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
break; // ENOSYS or other error — fall through to /dev/urandom
|
||||
}
|
||||
filled += static_cast<size_t>(ret);
|
||||
}
|
||||
if (filled == len) return true;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// POSIX fallback: /dev/urandom
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
{
|
||||
FILE* f = std::fopen("/dev/urandom", "rb");
|
||||
if (f) {
|
||||
while (filled < len) {
|
||||
size_t n = std::fread(buf + filled, 1, len - filled, f);
|
||||
if (n == 0) break;
|
||||
filled += n;
|
||||
}
|
||||
std::fclose(f);
|
||||
if (filled == len) return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Final fallback: std::random_device
|
||||
try
|
||||
{
|
||||
static std::mutex m;
|
||||
static std::random_device rd;
|
||||
std::lock_guard<std::mutex> lock(m);
|
||||
while (filled < len)
|
||||
{
|
||||
unsigned int r = rd();
|
||||
size_t to_copy = (len - filled < sizeof(r)) ? (len - filled) : sizeof(r);
|
||||
std::memcpy(buf + filled, &r, to_copy);
|
||||
filled += to_copy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns a cryptographically secure random unsigned int.
|
||||
static unsigned int RandUInt()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
SecureRandomBytes(reinterpret_cast<unsigned char*>(&result), sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // SECURE_RANDOM_BYTES_H
|
||||
@ -32,7 +32,6 @@
|
||||
#include "Unit.h"
|
||||
#include <cwchar>
|
||||
|
||||
|
||||
double Cm_To_Mm (const double &dValue)
|
||||
{
|
||||
return dValue * 10;
|
||||
@ -753,43 +752,6 @@ namespace XmlUtils
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
int Rand()
|
||||
{
|
||||
//rand returns integral value range between 0 and RAND_MAX.(RAND_MAX at least 32767.)
|
||||
static bool init = false; /* ensure different random header each time */
|
||||
if (!init)
|
||||
{
|
||||
init = true;
|
||||
srand((unsigned int) time(NULL));
|
||||
}
|
||||
return std::rand();
|
||||
}
|
||||
int GenerateInt()
|
||||
{
|
||||
//todo c++11 <random>
|
||||
return ((Rand() & 0x7FFF) | ((Rand() & 0x7FFF) << 15) | ((Rand() & 0x3) << 30));
|
||||
}
|
||||
|
||||
std::wstring GenerateGuid()
|
||||
{
|
||||
std::wstring result;
|
||||
//#if defined (_WIN32) || defined(_WIN64)
|
||||
// GUID guid;
|
||||
// CoCreateGuid(&guid);
|
||||
//
|
||||
// OLECHAR* guidString;
|
||||
// StringFromCLSID(guid, &guidString);
|
||||
//
|
||||
// result = std::wstring(guidString);
|
||||
//
|
||||
// CoTaskMemFree(guidString);
|
||||
//#else
|
||||
std::wstringstream sstream;
|
||||
sstream << boost::wformat(L"%04X%04X-%04X-%04X-%04X-%04X%04X%04X") % (Rand() & 0xff) % (Rand() & 0xff) % (Rand() & 0xff) % ((Rand() & 0x0fff) | 0x4000) % ((Rand() % 0x3fff) + 0x8000) % (Rand() & 0xff) % (Rand() & 0xff) % (Rand() & 0xff);
|
||||
result = sstream.str();
|
||||
//#endif
|
||||
return result;
|
||||
}
|
||||
std::wstring DoubleToString( double value, wchar_t* format )
|
||||
{
|
||||
if ( format == NULL ) return L"";
|
||||
@ -1050,3 +1012,31 @@ namespace XmlUtils
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
#include "./Rand.h"
|
||||
namespace XmlUtils
|
||||
{
|
||||
int GenerateInt()
|
||||
{
|
||||
return static_cast<int>(RandUInt());
|
||||
}
|
||||
|
||||
std::wstring GenerateGuid()
|
||||
{
|
||||
std::wstring result;
|
||||
|
||||
std::wstringstream sstream;
|
||||
sstream << boost::wformat(L"%04X%04X-%04X-%04X-%04X-%04X%04X%04X")
|
||||
% (RandUInt() & 0xffff)
|
||||
% (RandUInt() & 0xffff)
|
||||
% (RandUInt() & 0xffff)
|
||||
% ((RandUInt() & 0x0fff) | 0x4000)
|
||||
% ((RandUInt() & 0x3fff) | 0x8000)
|
||||
% (RandUInt() & 0xffff)
|
||||
% (RandUInt() & 0xffff)
|
||||
% (RandUInt() & 0xffff);
|
||||
result = sstream.str();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,6 +81,9 @@ namespace PPTX
|
||||
{
|
||||
pWriter->StartRecord(EFFECT_TYPE_ALPHAINV);
|
||||
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart);
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
|
||||
|
||||
pWriter->WriteRecord1(0, Color);
|
||||
|
||||
pWriter->EndRecord();
|
||||
|
||||
@ -87,6 +87,9 @@ namespace PPTX
|
||||
{
|
||||
pWriter->StartRecord(EFFECT_TYPE_ALPHAMOD);
|
||||
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart);
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
|
||||
|
||||
pWriter->WriteRecord1(0, cont);
|
||||
|
||||
pWriter->EndRecord();
|
||||
|
||||
@ -82,6 +82,9 @@ namespace PPTX
|
||||
{
|
||||
pWriter->StartRecord(EFFECT_TYPE_CLRREPL);
|
||||
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart);
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
|
||||
|
||||
pWriter->WriteRecord1(0, Color);
|
||||
|
||||
pWriter->EndRecord();
|
||||
|
||||
@ -82,6 +82,9 @@ namespace PPTX
|
||||
{
|
||||
pWriter->StartRecord(EFFECT_TYPE_FILL);
|
||||
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart);
|
||||
pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd);
|
||||
|
||||
pWriter->WriteRecord1(0, Fill);
|
||||
|
||||
pWriter->EndRecord();
|
||||
|
||||
@ -17,7 +17,8 @@ CONFIG += core_x2t
|
||||
include(../../../../Common/base.pri)
|
||||
|
||||
DEFINES += UNICODE _UNICODE \
|
||||
DONT_WRITE_EMBEDDED_FONTS
|
||||
DONT_WRITE_EMBEDDED_FONTS \
|
||||
CRYPTOPP_DISABLE_ASM
|
||||
|
||||
#BOOST
|
||||
include($$PWD/../../../../Common/3dParty/boost/boost.pri)
|
||||
|
||||
@ -25,15 +25,15 @@
|
||||
<Filter Include="Common">
|
||||
<UniqueIdentifier>{02739917-e580-44c9-9b2c-8e80c7a2164d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Sheets\Reader\XML">
|
||||
<UniqueIdentifier>{47d28884-9f95-479a-a812-cf3b0e0a6ac9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Sheets\Reader\CellFormat">
|
||||
<UniqueIdentifier>{3bf431c7-ab39-40bb-a5ce-dbc6008ae5e5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Draw">
|
||||
<UniqueIdentifier>{63d19e50-d1a5-4bc3-802f-062b7213a8a6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Sheets\CellFormat">
|
||||
<UniqueIdentifier>{3bf431c7-ab39-40bb-a5ce-dbc6008ae5e5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Sheets\XML">
|
||||
<UniqueIdentifier>{47d28884-9f95-479a-a812-cf3b0e0a6ac9}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\Binary\Document\BinWriter\BinaryWriterD.cpp">
|
||||
@ -115,43 +115,43 @@
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\columnNameController.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XLSXTableController.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XML2TableConverter.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLConverter2.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLMap.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLReader.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLReader2.cpp">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\CellFormatController\CellFormatController.cpp">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\CellFormatController\CurrencyReader.cpp">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\CellFormatController\DateReader.cpp">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\CellFormatController\DigitReader.cpp">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\ChartFromToBinary.cpp">
|
||||
<Filter>Sheets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Sheets\Reader\CellFormatController\LocalInfo.cpp">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\Binary\Document\DocWrapper\ChartSerializer.cpp" />
|
||||
<ClCompile Include="..\..\..\Binary\Document\DocWrapper\DocxSerializer.cpp" />
|
||||
@ -269,40 +269,40 @@
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\columnNamesController.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\XLSXTableController.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\XML2TableConverter.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLConverter2.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLMap.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\XMLReader\XMLReader.h">
|
||||
<Filter>Sheets\Reader\XML</Filter>
|
||||
<Filter>Sheets\XML</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\CellFormatController\CellFormatController.h">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\CellFormatController\CurrencyReader.h">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\CellFormatController\DateReader.h">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\CellFormatController\DigitReader.h">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\ChartFromToBinary.h">
|
||||
<Filter>Sheets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Sheets\Reader\CellFormatController\LocalInfo.h">
|
||||
<Filter>Sheets\Reader\CellFormat</Filter>
|
||||
<Filter>Sheets\CellFormat</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\Binary\Document\DocWrapper\DocxSerializer.h" />
|
||||
<ClInclude Include="..\..\..\Binary\Document\DocWrapper\FontProcessor.h" />
|
||||
|
||||
@ -59,7 +59,7 @@ namespace OOX
|
||||
writer.WriteString(L"<person");
|
||||
WritingStringNullableAttrEncodeXmlString(L"displayName", displayName, *displayName);
|
||||
WritingStringNullableAttrString(L"id", id, *id);
|
||||
WritingStringNullableAttrString(L"userId", userId, *userId);
|
||||
WritingStringNullableAttrEncodeXmlString(L"userId", userId, *userId);
|
||||
WritingStringNullableAttrEncodeXmlString(L"providerId", providerId, *providerId);
|
||||
writer.WriteString(L"/>");
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ namespace OOX
|
||||
return;
|
||||
}
|
||||
|
||||
if(SimpleTypes::Spreadsheet::celltypeStr == eType || SimpleTypes::Spreadsheet::celltypeInlineStr == eType)
|
||||
if(SimpleTypes::Spreadsheet::celltypeStr == eType || SimpleTypes::Spreadsheet::celltypeInlineStr == eType || SimpleTypes::Spreadsheet::celltypeDate == eType)
|
||||
{
|
||||
m_bIsInit = true;
|
||||
m_oValue.fromXML(oReader, SimpleTypes::xmlspacePreserve == m_oSpace.GetValue());
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
#include "../ComplexTypes_Spreadsheet.h"
|
||||
|
||||
#include "../../Binary/Presentation/BinaryFileReaderWriter.h"
|
||||
#include "../../Binary/Sheets/Reader/CellFormatController/DateReader.h"
|
||||
#include "../../Binary/Sheets/Writer/CSVWriter.h"
|
||||
#include "../../../DesktopEditor/common/StreamWriter.h"
|
||||
#include "../../../DesktopEditor/common/StringExt.h"
|
||||
@ -662,8 +663,22 @@ namespace OOX
|
||||
case SimpleTypes::Spreadsheet::celltypeSharedString: nType = XLSB::rt_CellIsst; break;
|
||||
case SimpleTypes::Spreadsheet::celltypeError: nType = XLSB::rt_CellError; break;
|
||||
case SimpleTypes::Spreadsheet::celltypeBool: nType = XLSB::rt_CellBool; break;
|
||||
case SimpleTypes::Spreadsheet::celltypeDate:
|
||||
{
|
||||
std::wstring tmp(m_oValue.m_oValue.m_sBuffer, m_oValue.m_oValue.m_nLen);
|
||||
DateReader dateChecker;
|
||||
double result = 0;
|
||||
bool bTime = false, bDate = false;
|
||||
if (dateChecker.GetDigitalDate(tmp, result, bDate, bTime))
|
||||
{
|
||||
nType = XLSB::rt_CellReal;
|
||||
m_oValue.m_dValue = result;
|
||||
}
|
||||
else if (m_oValue.m_oValue.m_nLen > 0)
|
||||
nType = XLSB::rt_CellSt;
|
||||
}break;
|
||||
case SimpleTypes::Spreadsheet::celltypeInlineStr:
|
||||
case SimpleTypes::Spreadsheet::celltypeStr: nType = XLSB::rt_CellSt; break;
|
||||
case SimpleTypes::Spreadsheet::celltypeStr: nType = XLSB::rt_CellSt; break;
|
||||
}
|
||||
}
|
||||
bool bIsBlankFormula = false;
|
||||
@ -730,28 +745,31 @@ namespace OOX
|
||||
oStream.XlsbStartRecord(nType, nLen);
|
||||
oStream.WriteULONG(m_nCol & 0x3FFF);
|
||||
|
||||
|
||||
oStream.WriteULONG(nFlags2);
|
||||
//todo RkNumber
|
||||
switch(nType)
|
||||
switch (nType)
|
||||
{
|
||||
case XLSB::rt_CellReal:
|
||||
case XLSB::rt_FmlaNum:
|
||||
case XLSB::rt_CellReal:
|
||||
case XLSB::rt_FmlaNum:
|
||||
{
|
||||
oStream.WriteDoubleReal(m_oValue.m_dValue);
|
||||
break;
|
||||
case XLSB::rt_CellIsst:
|
||||
}break;
|
||||
case XLSB::rt_CellIsst:
|
||||
{
|
||||
oStream.WriteULONG(m_oValue.m_nValue);
|
||||
break;
|
||||
case XLSB::rt_CellSt:
|
||||
case XLSB::rt_FmlaString:
|
||||
}break;
|
||||
case XLSB::rt_CellSt:
|
||||
case XLSB::rt_FmlaString:
|
||||
{
|
||||
oStream.WriteStringData(m_oValue.m_oValue.m_sBuffer, m_oValue.m_oValue.m_nLen);
|
||||
break;
|
||||
case XLSB::rt_CellError:
|
||||
case XLSB::rt_FmlaError:
|
||||
case XLSB::rt_CellBool:
|
||||
case XLSB::rt_FmlaBool:
|
||||
}break;
|
||||
case XLSB::rt_CellError:
|
||||
case XLSB::rt_FmlaError:
|
||||
case XLSB::rt_CellBool:
|
||||
case XLSB::rt_FmlaBool:
|
||||
{
|
||||
oStream.WriteBYTE(m_oValue.m_nValue);
|
||||
break;
|
||||
}break;
|
||||
}
|
||||
|
||||
_UINT16 nFlags = 0;
|
||||
|
||||
@ -33,3 +33,9 @@ HEADERS += \
|
||||
$$PWD/typeConversion.h \
|
||||
$$PWD/typeselements.h \
|
||||
$$PWD/TFormulaSize.h
|
||||
|
||||
core_mac | core_ios {
|
||||
LIBS += -framework Security
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -30,6 +30,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test utility. NOT used in production builds.
|
||||
*
|
||||
* This code is intended solely for local debugging and verification
|
||||
* of internal components by developers. Security concerns
|
||||
* (error handling, input validation, protection against race conditions,
|
||||
* buffer overflows, etc.) are intentionally not addressed in this file
|
||||
* and are not applicable.
|
||||
*/
|
||||
|
||||
#include "./../source/ECMACryptFile.h"
|
||||
#include "./../../DesktopEditor/common/File.h"
|
||||
#include "./../../Common/3dParty/openssl/common/common_openssl.h"
|
||||
|
||||
@ -1098,7 +1098,10 @@ bool CPdfEditor::IncrementalUpdates()
|
||||
return true;
|
||||
|
||||
m_nMode = Mode::WriteAppend;
|
||||
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0);
|
||||
PDFDoc* pPDFDocument = NULL;
|
||||
PdfReader::CPdfFontList* pFontList = NULL;
|
||||
int nStartRefID = 0;
|
||||
m_pReader->GetPageIndex(0, &pPDFDocument, &pFontList, &nStartRefID);
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
|
||||
|
||||
@ -1330,14 +1333,28 @@ bool CPdfEditor::IncrementalUpdates()
|
||||
bRes = pDoc->EditResources(pDRXref, pDR);
|
||||
}
|
||||
pagesRefObj.free();
|
||||
|
||||
if (form)
|
||||
{
|
||||
Object oDR;
|
||||
Object* oAcroForm = form->getAcroFormObj();
|
||||
if (oAcroForm->dictLookup("DR", &oDR)->isDict())
|
||||
{
|
||||
Dict* pResources = oDR.getDict();
|
||||
ScanFonts(pPDFDocument, pResources);
|
||||
}
|
||||
oDR.free();
|
||||
}
|
||||
return bRes;
|
||||
}
|
||||
void CPdfEditor::NewFrom()
|
||||
{
|
||||
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
|
||||
Object oCatalog;
|
||||
PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0);
|
||||
PDFDoc* pPDFDocument = NULL;
|
||||
PdfReader::CPdfFontList* pFontList = NULL;
|
||||
int nStartRefID = 0;
|
||||
m_pReader->GetPageIndex(0, &pPDFDocument, &pFontList, &nStartRefID);
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
if (!xref->getCatalog(&oCatalog)->isDict())
|
||||
{
|
||||
@ -1564,8 +1581,12 @@ void CPdfEditor::NewFrom()
|
||||
}
|
||||
}
|
||||
}
|
||||
oTemp2.free(); oTemp.free();
|
||||
oTemp2.free();
|
||||
pDR->Fix();
|
||||
|
||||
Dict* pResources = oTemp.getDict();
|
||||
ScanFonts(pPDFDocument, pResources);
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@ -2724,7 +2745,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD
|
||||
}
|
||||
}
|
||||
}
|
||||
oTemp2.free(); oTemp.free();
|
||||
oTemp2.free();
|
||||
|
||||
Dict* pResources = oTemp.getDict();
|
||||
ScanFonts(pPDFDocument, pResources);
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@ -4189,12 +4214,7 @@ void CPdfEditor::ClearPage()
|
||||
// Mode::WriteAppend && Mode::WriteNew
|
||||
// Reading and processing fonts from page
|
||||
Dict* pResources = pOPage->getResourceDict();
|
||||
if (pResources)
|
||||
{
|
||||
std::vector<int> arrUniqueResources;
|
||||
ScanAndProcessFonts(pPDFDocument, xref, pResources, 0, arrUniqueResources, pFontList, nStartRefID);
|
||||
m_pReader->SetFonts(m_nEditPage);
|
||||
}
|
||||
ScanFonts(pPDFDocument, pResources);
|
||||
oAnnots.free();
|
||||
}
|
||||
void CPdfEditor::AddShapeXML(const std::string& sXML)
|
||||
@ -4443,6 +4463,18 @@ std::vector<double> CPdfEditor::WriteRedact(const std::vector<std::wstring>& arr
|
||||
}
|
||||
return arrRes;
|
||||
}
|
||||
void CPdfEditor::ScanFonts(PDFDoc* pPDFDocument, Dict* pResources)
|
||||
{
|
||||
if (!pResources)
|
||||
return;
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
int nStartRefID = m_pReader->GetStartRefID(pPDFDocument);
|
||||
PdfReader::CPdfFontList* pFontList = m_pReader->GetFontList(pPDFDocument);
|
||||
|
||||
std::vector<int> arrUniqueResources;
|
||||
ScanAndProcessFonts(pPDFDocument, xref, pResources, 0, arrUniqueResources, pFontList, nStartRefID);
|
||||
m_pReader->SetFonts(pFontList);
|
||||
}
|
||||
void CPdfEditor::ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pResources, int nDepth, std::vector<int>& arrUniqueResources, PdfReader::CPdfFontList* pFontList, int nStartRefID)
|
||||
{
|
||||
if (nDepth > 5 || !pResources)
|
||||
|
||||
@ -116,6 +116,7 @@ private:
|
||||
bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID);
|
||||
bool ChangeFullNameParent(int nParent, const std::string& sPrefixForm, std::vector<int>& arrRename);
|
||||
void ScanAndProcessFonts(PDFDoc* pPDFDocument, XRef* xref, Dict* pResources, int nDepth, std::vector<int>& arrUniqueResources, PdfReader::CPdfFontList* pFontList, int nStartRefID);
|
||||
void ScanFonts(PDFDoc* pPDFDocument, Dict* pResources);
|
||||
|
||||
struct CRedactData
|
||||
{
|
||||
|
||||
@ -508,7 +508,12 @@ BYTE* CPdfFile::GetWidgets()
|
||||
void CPdfFile::SetPageFonts(int nPageIndex)
|
||||
{
|
||||
if (m_pInternal->pReader)
|
||||
m_pInternal->pReader->SetFonts(nPageIndex);
|
||||
{
|
||||
PDFDoc* pDoc = NULL;
|
||||
PdfReader::CPdfFontList* pFontList = NULL;
|
||||
m_pInternal->pReader->GetPageIndex(nPageIndex, &pDoc, &pFontList);
|
||||
m_pInternal->pReader->SetFonts(pFontList);
|
||||
}
|
||||
}
|
||||
BYTE* CPdfFile::GetAnnotEmbeddedFonts()
|
||||
{
|
||||
@ -1444,6 +1449,34 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command)
|
||||
if (nFlags & (1 << 15))
|
||||
m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetCopyAP());
|
||||
}
|
||||
if (pCommand->IsWidget())
|
||||
{
|
||||
CAnnotFieldInfo::CWidgetAnnotPr* pPr = pCommand->GetWidgetAnnotPr();
|
||||
std::wstring wsFontName = pPr->GetFontName();
|
||||
|
||||
size_t lastSpace = wsFontName.find_last_of(L' ');
|
||||
if (lastSpace != std::wstring::npos && lastSpace + 1 == wsFontName.size() - 32)
|
||||
{
|
||||
std::wstring sHash = wsFontName.substr(lastSpace + 1);
|
||||
bool bValidHash = true;
|
||||
for (wchar_t c : sHash)
|
||||
{
|
||||
if (!((c >= L'A' && c <= L'F') || (c >= L'0' && c <= L'9')))
|
||||
{
|
||||
bValidHash = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bValidHash)
|
||||
{
|
||||
std::wstring sName = wsFontName.substr(0, lastSpace);
|
||||
wsFontName = sName;
|
||||
}
|
||||
}
|
||||
|
||||
pPr->SetFontName(wsFontName);
|
||||
}
|
||||
}
|
||||
return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand);
|
||||
}
|
||||
|
||||
@ -210,3 +210,7 @@ SOURCES += PdfFile.cpp \
|
||||
PdfReader.cpp \
|
||||
PdfEditor.cpp \
|
||||
OnlineOfficeBinToPdf.cpp
|
||||
|
||||
core_mac | core_ios {
|
||||
LIBS += -framework Security
|
||||
}
|
||||
|
||||
@ -245,6 +245,18 @@ int CPdfReader::GetNumPagesBefore(PDFDoc* _pDoc)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
PdfReader::CPdfFontList* CPdfReader::GetFontList(PDFDoc* _pDoc)
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
{
|
||||
if (!pPDFContext || !pPDFContext->m_pDocument)
|
||||
continue;
|
||||
PDFDoc* pDoc = pPDFContext->m_pDocument;
|
||||
if (_pDoc == pDoc)
|
||||
return pPDFContext->m_pFontList;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
std::string CPdfReader::GetPrefixForm(PDFDoc* _pDoc)
|
||||
{
|
||||
for (CPdfReaderContext* pPDFContext : m_vPDFContext)
|
||||
@ -1299,15 +1311,11 @@ BYTE* CPdfReader::GetWidgets()
|
||||
oRes.ClearWithoutAttack();
|
||||
return bRes;
|
||||
}
|
||||
void CPdfReader::SetFonts(int _nPageIndex)
|
||||
void CPdfReader::SetFonts(PdfReader::CPdfFontList* pFontList)
|
||||
{
|
||||
if (m_vPDFContext.empty())
|
||||
return;
|
||||
|
||||
PDFDoc* pDoc = NULL;
|
||||
PdfReader::CPdfFontList* pFontList = NULL;
|
||||
GetPageIndex(_nPageIndex, &pDoc, &pFontList);
|
||||
|
||||
const std::map<Ref, PdfReader::TFontEntry*>& mapFonts = pFontList->GetFonts();
|
||||
for (std::map<Ref, PdfReader::TFontEntry*>::const_iterator it = mapFonts.begin(); it != mapFonts.end(); ++it)
|
||||
{
|
||||
|
||||
@ -110,11 +110,12 @@ public:
|
||||
PDFDoc* GetPDFDocument(int PDFIndex);
|
||||
int GetStartRefID(PDFDoc* pDoc);
|
||||
int GetNumPagesBefore(PDFDoc* pDoc);
|
||||
PdfReader::CPdfFontList* GetFontList(PDFDoc* pDoc);
|
||||
std::string GetPrefixForm(PDFDoc* pDoc);
|
||||
int FindRefNum(int nObjID, PDFDoc** pDoc = NULL, int* nStartRefID = NULL);
|
||||
int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL, int* nStartRefID = NULL);
|
||||
|
||||
void SetFonts(int nPageIndex);
|
||||
void SetFonts(PdfReader::CPdfFontList* pFontList);
|
||||
BYTE* GetStructure();
|
||||
BYTE* GetLinks(int nPageIndex);
|
||||
BYTE* GetWidgets();
|
||||
|
||||
@ -2674,6 +2674,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF
|
||||
CAnnotFieldInfo::CWidgetAnnotPr::CSignatureWidgetPr* pPr = oInfo.GetWidgetAnnotPr()->GetSignatureWidgetPr();
|
||||
PdfWriter::CSignatureWidget* pSignatureWidget = (PdfWriter::CSignatureWidget*)pAnnot;
|
||||
}
|
||||
|
||||
if (m_bSplit)
|
||||
pWidgetAnnot->RemoveAP();
|
||||
}
|
||||
else if (oInfo.IsLink())
|
||||
{
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include "./../../OOXML/Base/Rand.h"
|
||||
|
||||
namespace PdfWriter
|
||||
{
|
||||
@ -3669,7 +3670,7 @@ namespace PdfWriter
|
||||
CharStringOperand newOperand;
|
||||
|
||||
newOperand.IsInteger = false;
|
||||
newOperand.RealValue = ((double)rand() + 1) / ((double)RAND_MAX + 1);
|
||||
newOperand.RealValue = ((double)RandUInt() + 1) / ((double)RAND_MAX + 1);
|
||||
|
||||
mOperandStack.push_back(newOperand);
|
||||
return inProgramCounter;
|
||||
|
||||
@ -4082,6 +4082,15 @@ void Gfx::opXObject(Object args[], int numArgs) {
|
||||
Object opiDict;
|
||||
#endif
|
||||
|
||||
double *ctm;
|
||||
double det;
|
||||
|
||||
ctm = state->getCTM();
|
||||
det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
|
||||
if (fabs(det) <= 1e-10) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ocState && !out->needCharCount()) {
|
||||
return;
|
||||
}
|
||||
|
||||
9
Test/Applications/README.md
Normal file
9
Test/Applications/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Test utilities. NOT used in production builds.
|
||||
*
|
||||
* This code is intended solely for local debugging and verification
|
||||
* of internal components by developers. Security concerns
|
||||
* (error handling, input validation, protection against race conditions,
|
||||
* buffer overflows, etc.) are intentionally not addressed in this file
|
||||
* and are not applicable.
|
||||
*/
|
||||
@ -100,45 +100,8 @@ const std::vector<std::string> TxtFile::readUtf8Lines(int IdxEncoding)
|
||||
{
|
||||
unicode_content = conv.toUnicode(file_data.get(), read_size, 65001);
|
||||
}
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
std::wstring regular_text;
|
||||
std::string utf8_result;
|
||||
|
||||
for (size_t i = 0; i < unicode_content.size(); i++)
|
||||
{
|
||||
unsigned int cp = static_cast<unsigned int>(unicode_content[i]);
|
||||
|
||||
if (cp > 0xFFFF)
|
||||
{
|
||||
|
||||
if (!regular_text.empty())
|
||||
{
|
||||
utf8_result += conv.fromUnicode(regular_text, "UTF-8");
|
||||
regular_text.clear();
|
||||
}
|
||||
|
||||
|
||||
utf8_result += static_cast<char>(0xF0 | ((cp >> 18) & 0x07));
|
||||
utf8_result += static_cast<char>(0x80 | ((cp >> 12) & 0x3F));
|
||||
utf8_result += static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
|
||||
utf8_result += static_cast<char>(0x80 | (cp & 0x3F));
|
||||
}
|
||||
else
|
||||
{
|
||||
regular_text += unicode_content[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!regular_text.empty())
|
||||
{
|
||||
utf8_result += conv.fromUnicode(regular_text, "UTF-8");
|
||||
}
|
||||
|
||||
utf8_content = utf8_result;
|
||||
#else
|
||||
utf8_content = conv.fromUnicode(unicode_content, "UTF-8");
|
||||
#endif
|
||||
}
|
||||
size_t lineCount = 0;
|
||||
if (!utf8_content.empty())
|
||||
|
||||
@ -105,6 +105,8 @@ namespace NSUnicodeConverter
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
int32_t nUCharCapacity = (int32_t)nInputLen;// UTF-16 uses 2 code-points per char
|
||||
if (sizeof(wchar_t) > 2)
|
||||
nUCharCapacity *= 2;
|
||||
|
||||
UChar* pUChar = new UChar[(uint32_t)nUCharCapacity * sizeof(UChar)];
|
||||
if (pUChar)
|
||||
@ -169,8 +171,9 @@ namespace NSUnicodeConverter
|
||||
if (U_SUCCESS(status))
|
||||
{
|
||||
int32_t nUCharCapacity = (int32_t)nInputLen;// UTF-16 uses 2 code-points per char
|
||||
if (sizeof(wchar_t) > 2)
|
||||
nUCharCapacity *= 2;
|
||||
|
||||
//UChar* pUChar = new UChar[nUCharCapacity];
|
||||
UChar* pUChar = (UChar*)malloc((uint32_t)nUCharCapacity * sizeof(UChar));
|
||||
if (pUChar)
|
||||
{
|
||||
@ -196,7 +199,7 @@ namespace NSUnicodeConverter
|
||||
sRes.clear();
|
||||
}
|
||||
}
|
||||
//delete []pUCharStart;
|
||||
free(pUChar);
|
||||
}
|
||||
ucnv_close(conv);
|
||||
}
|
||||
|
||||
@ -46,3 +46,7 @@ include(X2tConverter.pri)
|
||||
HEADERS += ../../src/dylib/x2t.h
|
||||
SOURCES += ../../src/dylib/x2t.cpp
|
||||
}
|
||||
|
||||
core_mac | core_ios {
|
||||
LIBS += -framework Security
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user