From 1c8068c8cf25bb348d2eaf1f6247fb028c943f3b Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Wed, 21 Oct 2026 09:06:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=B8=B4=E6=97=B6=20SAT=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=90=8D=E5=94=AF=E4=B8=80=E5=8C=96=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E8=B6=8A=E7=95=8C=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RegionToString/StringToRegion/BodyToString/StringToFace 的临时文件名 由固定的 Region1/Region2/Region121/Region212/Region312.sat 改为 x3d__<序号>.sat,多 CAD 实例或多线程并发时不再互相覆盖 - 读取缓冲区补 +1 零字节,修复 new char[len] 无结尾 0 导致的越界读 - 检查 file.Read 短读,失败时释放缓冲并返回空 - 用完即 DeleteFile,不残留临时文件 --- SourceCode/Code2026/CoreCommand/CoreTools.cpp | 126 ++++++++++++------ 1 file changed, 88 insertions(+), 38 deletions(-) diff --git a/SourceCode/Code2026/CoreCommand/CoreTools.cpp b/SourceCode/Code2026/CoreCommand/CoreTools.cpp index 5763c36..2dbcc52 100644 --- a/SourceCode/Code2026/CoreCommand/CoreTools.cpp +++ b/SourceCode/Code2026/CoreCommand/CoreTools.cpp @@ -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; }