Merge pull request 'fix: fixACISFormat 改为显式长度入参,修正 npos 与越界读' (#26) from company-desktop-computer/fix/acis-format-bounds into main
Reviewed-on: https://git.ethereal-realm.top/gjm/envi-code/pulls/26 Reviewed-by: gjm <littleoldpan@163.com>
This commit was merged in pull request #26.
This commit is contained in:
commit
10d1fc00c8
1 file changed
+23
-15
@@ -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<CString> 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();
|
||||
|
||||
Reference in new issue
Block a user