fix: 临时 SAT 文件名唯一化并修正越界读 #22

Merged
gjm merged 1 commits from company-desktop-computer/refactor/x3dsolid-tempfile AGit into main 2026-10-21 09:11:18 +08:00
Showing only changes of commit 1c8068c8cf - Show all commits
+88 -38
View File
@@ -3034,16 +3034,31 @@ AcDbRegion* CoreTools::createRegion(AcDbEntity *pEnt)
return (AcDbRegion*)segs[0];
}
// 生成唯一的临时 SAT 文件路径。
// 用 PID + 进程内原子序号,避免多个 CAD 实例或多线程互相覆盖同名文件。
// 调用方负责在 acisOut/acisIn 结束后 DeleteFile。
static CString MakeTempSatPath()
{
static LONG s_nSeq = 0;
LONG nSeq = ::InterlockedIncrement(&s_nSeq);
CString sPath = FilePath::getSystemTemporaryFolder();
if (sPath.IsEmpty())
sPath = _T(".");
CString sName;
sName.Format(_T("\\x3d_%lu_%ld.sat"), (unsigned long)::GetCurrentProcessId(), nSeq);
return sPath + sName;
}
Adesk::UInt64 CoreTools::RegionToString(const AcDbRegion *pReg, char *& pszTxt)
{
Adesk::UInt64 dwFileLength = 0;
pszTxt = NULL;
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region121.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return 0;
CString sLine;
AcDbVoidPtrArray arBodyPtrs;
arBodyPtrs.append((void *)pReg);
@@ -3054,12 +3069,24 @@ Adesk::UInt64 CoreTools::RegionToString(const AcDbRegion *pReg, char *& pszTxt)
CFile file;
if (file.Open(sFullPath, CFile::modeRead))
{
dwFileLength = file.GetLength();
pszTxt = new char[dwFileLength];
::memset(pszTxt, 0, sizeof(char) * dwFileLength);
file.Read(pszTxt, (UINT)dwFileLength);
ULONGLONG nFileLength = file.GetLength();
if (nFileLength > 0 && nFileLength < (ULONGLONG)UINT_MAX)
{
pszTxt = new char[(size_t)nFileLength + 1];
::memset(pszTxt, 0, (size_t)nFileLength + 1);
UINT nRead = file.Read(pszTxt, (UINT)nFileLength);
if (nRead == (UINT)nFileLength)
{
dwFileLength = nFileLength;
}
else
{
acutPrintf(_T("\nCoreTools::RegionToString short read %u/%I64u."), nRead, nFileLength);
delete[] pszTxt;
pszTxt = NULL;
}
}
file.Close();
}
else
@@ -3071,16 +3098,16 @@ Adesk::UInt64 CoreTools::RegionToString(const AcDbRegion *pReg, char *& pszTxt)
{
acutPrintf(_T("\nCoreTools::RegionToString::acisOut failure. ERRNO %d."), es);
}
::DeleteFile(sFullPath);
return dwFileLength;
}
bool CoreTools::RegionToString(const AcDbRegion * pReg, CString & sRegionScrp)
{
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region1.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return false;
CString sLine;
AcDbVoidPtrArray arBodyPtrs;
arBodyPtrs.append((void*)pReg);
@@ -3091,15 +3118,20 @@ bool CoreTools::RegionToString(const AcDbRegion * pReg, CString & sRegionScrp)
CFile file;
if (file.Open(sFullPath, CFile::modeRead))
{
ULONGLONG dwFileLength = file.GetLength();
char* pszTxt = new char[dwFileLength];
::memset(pszTxt, 0, sizeof(char) * dwFileLength);
ULONGLONG nFileLength = file.GetLength();
if (nFileLength > 0 && nFileLength < (ULONGLONG)UINT_MAX)
{
char* pszTxt = new char[(size_t)nFileLength + 1];
::memset(pszTxt, 0, (size_t)nFileLength + 1);
file.Read(pszTxt, (UINT)dwFileLength);
sRegionScrp = pszTxt;
delete[] pszTxt;
UINT nRead = file.Read(pszTxt, (UINT)nFileLength);
if (nRead == (UINT)nFileLength)
sRegionScrp = pszTxt;
else
acutPrintf(_T("\nCoreTools::RegionToString short read %u/%I64u."), nRead, nFileLength);
delete[] pszTxt;
}
file.Close();
}
else
@@ -3111,6 +3143,8 @@ bool CoreTools::RegionToString(const AcDbRegion * pReg, CString & sRegionScrp)
{
acutPrintf(_T("\nCoreTools::RegionToString::acisOut failure. ERRNO %d."), es);
}
::DeleteFile(sFullPath);
return sRegionScrp.IsEmpty() ? false : true;
}
@@ -3481,9 +3515,9 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp)
if (!fixACISFormat(sUtf8.c_str(), sNewSrc)) return NULL;
CFile file;
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region2.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return NULL;
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
{
file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size());
@@ -3492,6 +3526,7 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp)
else
{
acutPrintf(_T("\nCoreTools::StringToRegion write file failure."));
::DeleteFile(sFullPath);
return NULL;
}
@@ -3519,6 +3554,7 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp)
for (int i = 0; i < arBodyPtrs.length(); ++i)
DELETE_PTR(arBodyPtrs[i]);
::DeleteFile(sFullPath);
return pReg;
}
@@ -3528,9 +3564,8 @@ AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg)
if (!fixACISFormat(pszReg, sNewSrc)) return NULL;
AcDbRegion *pReg(NULL);
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region212.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return NULL;
CFile file;
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
@@ -3541,6 +3576,7 @@ AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg)
else
{
acutPrintf(_T("\nCoreTools::StringToRegion write file failure."));
::DeleteFile(sFullPath);
return NULL;
}
@@ -3567,6 +3603,7 @@ AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg)
for (int i = 0; i < arBodyPtrs.length(); ++i)
DELETE_PTR(arBodyPtrs[i]);
::DeleteFile(sFullPath);
return pReg;
}
@@ -3575,11 +3612,9 @@ Adesk::UInt64 CoreTools::BodyToString(const AcDbBody *pBody, char *&pszOut)
Adesk::UInt64 dwFileLength = 0;
pszOut = NULL;
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region121.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return 0;
CString sLine;
AcDbVoidPtrArray arBodyPtrs;
arBodyPtrs.append((void *)pBody);
@@ -3590,12 +3625,24 @@ Adesk::UInt64 CoreTools::BodyToString(const AcDbBody *pBody, char *&pszOut)
CFile file;
if (file.Open(sFullPath, CFile::modeRead))
{
dwFileLength = file.GetLength();
pszOut = new char[dwFileLength];
::memset(pszOut, 0, sizeof(char) * dwFileLength);
file.Read(pszOut, (UINT)dwFileLength);
ULONGLONG nFileLength = file.GetLength();
if (nFileLength > 0 && nFileLength < (ULONGLONG)UINT_MAX)
{
pszOut = new char[(size_t)nFileLength + 1];
::memset(pszOut, 0, (size_t)nFileLength + 1);
UINT nRead = file.Read(pszOut, (UINT)nFileLength);
if (nRead == (UINT)nFileLength)
{
dwFileLength = nFileLength;
}
else
{
acutPrintf(_T("\nCoreTools::BodyToString short read %u/%I64u."), nRead, nFileLength);
delete[] pszOut;
pszOut = NULL;
}
}
file.Close();
}
else
@@ -3607,15 +3654,16 @@ Adesk::UInt64 CoreTools::BodyToString(const AcDbBody *pBody, char *&pszOut)
{
acutPrintf(_T("\nCoreTools::BodyToString::acisOut failure. ERRNO %d."), es);
}
::DeleteFile(sFullPath);
return dwFileLength;
}
AcDbSurface *CoreTools::StringToFace(Adesk::UInt64 nLen, char *pszBody)
{
AcDbSurface *pFace(NULL);
CString sFullPath = FilePath::getSystemTemporaryFolder();
sFullPath.MakeLower();
sFullPath += _T("\\Region312.sat");
CString sFullPath = MakeTempSatPath();
if (sFullPath.IsEmpty()) return NULL;
CFile file;
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
@@ -3626,6 +3674,7 @@ AcDbSurface *CoreTools::StringToFace(Adesk::UInt64 nLen, char *pszBody)
else
{
acutPrintf(_T("\nCoreTools::StringToBody write file failure."));
::DeleteFile(sFullPath);
return NULL;
}
@@ -3670,6 +3719,7 @@ AcDbSurface *CoreTools::StringToFace(Adesk::UInt64 nLen, char *pszBody)
for (int i = 0; i < arBodyPtrs.length(); ++i)
DELETE_PTR(arBodyPtrs[i]);
::DeleteFile(sFullPath);
return pFace;
}