From 6e494aeb9edfe4a3682032a4d2186bc4b0eff018 Mon Sep 17 00:00:00 2001 From: company-desktop-computer Date: Wed, 21 Oct 2026 14:15:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20fixACISFormat=20=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E6=98=BE=E5=BC=8F=E9=95=BF=E5=BA=A6=E5=85=A5=E5=8F=82=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20npos=20=E4=B8=8E=E8=B6=8A=E7=95=8C?= =?UTF-8?q?=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 签名加 size_t nLen,内部用 std::string(pszReg, nLen) 构造, 不再依赖调用方 buffer 的结尾 '\0';StringToRegion(nLen, char*) 传入的 m_pSatBuffer 是 new byte[m_nSatLen],没有终止符,原写法会越界读 - 首行解析改用 substr(0, find('\n')),去掉 stringstream 对终止符的依赖 - pos == npos(数据里没有 '#')时返回 false,原写法 pos+1 溢出为 0, substr(0,0) 得到空串却仍返回 true,调用方会写出 0 字节文件且无提示 - countOfRecord <= 0 时提前返回 false --- SourceCode/Code2026/CoreCommand/CoreTools.cpp | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/SourceCode/Code2026/CoreCommand/CoreTools.cpp b/SourceCode/Code2026/CoreCommand/CoreTools.cpp index f53d7a9..22cb767 100644 --- a/SourceCode/Code2026/CoreCommand/CoreTools.cpp +++ b/SourceCode/Code2026/CoreCommand/CoreTools.cpp @@ -3069,35 +3069,43 @@ namespace return std::string::npos; } - // 整理sat文件格式,使其符合规范 - bool fixACISFormat(const char *pszReg, std::string &sOut) + // 整理sat数据,只保留到第 countOfRecord 条 data record 的结尾。 + // 数据尾部可能跟着非 SAT 内容(越界读的残留、旧实现追加的标记等),靠记录数反推真实结尾。 + // nLen 必须显式传入:调用方的 buffer 不保证有结尾 '\0'(如 m_pSatBuffer)。 + bool fixACISFormat(const char *pszReg, size_t nLen, std::string &sOut) { - // 先取第一行,得到data record 的数量 - std::string ss; - std::stringstream eam(pszReg); - std::getline(eam, ss); - if (ss.empty()) return false; + if (pszReg == NULL || nLen == 0) return false; + + const std::string sSrc(pszReg, nLen); + + // 先取第一行,得到data record 的数量 + const std::string sFirstLine = sSrc.substr(0, sSrc.find('\n')); + if (sFirstLine.empty()) return false; std::vector nums; - CoreTools::SplitString(CString(ss.c_str()), _T(" "), nums); + CoreTools::SplitString(CString(sFirstLine.c_str()), _T(" "), nums); if (nums.size() < 2) return false; int countOfRecord = _ttoi((LPCTSTR)nums[1]); + if (countOfRecord <= 0) return false; - ss = pszReg; - int sharpCount = std::count(ss.begin() ,ss.end(), '#'); + int sharpCount = (int)std::count(sSrc.begin(), sSrc.end(), '#'); size_t pos(std::string::npos); if (sharpCount > countOfRecord) { // 如果 sharpCount 大于 countOfRecord,从头部取到第sharpCount个‘#’位置 - pos = find_nth_occurrence_reverse(ss, '#', (sharpCount - countOfRecord + 1)); + pos = find_nth_occurrence_reverse(sSrc, '#', (size_t)(sharpCount - countOfRecord + 1)); } else // <= { // 如果 sharpCount 小于等于 countOfRecord,直接从头部取到最后一个‘#’位置 - pos = ss.rfind('#'); + pos = sSrc.rfind('#'); } - sOut = ss.substr(0, pos + 1); + + // 没有记录分隔符,说明数据不可用,不能返回空串让调用方误以为成功 + if (pos == std::string::npos) return false; + + sOut = sSrc.substr(0, pos + 1); sOut += "\n\r"; return true; } @@ -3512,7 +3520,7 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp) { std::string sUtf8 = CoreTools::unicode2Ansii((LPCTSTR)sRegionScrp, CP_UTF8); std::string sNewSrc; - if (!fixACISFormat(sUtf8.c_str(), sNewSrc)) return NULL; + if (!fixACISFormat(sUtf8.c_str(), sUtf8.size(), sNewSrc)) return NULL; CFile file; CString sFullPath = MakeTempSatPath(); @@ -3561,7 +3569,7 @@ AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp) AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg) { std::string sNewSrc; - if (!fixACISFormat(pszReg, sNewSrc)) return NULL; + if (!fixACISFormat(pszReg, (size_t)nLen, sNewSrc)) return NULL; AcDbRegion *pReg(NULL); CString sFullPath = MakeTempSatPath();