|
@@ -220,66 +220,86 @@ bool ParsePtToDataObject(ResDataObject &obj,ptree &pt)
|
|
|
|
|
|
}
|
|
|
|
|
|
-bool ParseDataObjectToPt(ptree& pt, ResDataObject& obj)
|
|
|
-{
|
|
|
- //std::cout << "[ParseDataObjectToPt] Entering function, object size: " << obj.size() << std::endl;
|
|
|
- const size_t objSize = obj.size();
|
|
|
-
|
|
|
- for (size_t i = 0; i < objSize; i++)
|
|
|
- {
|
|
|
- //std::cout << "[ParseDataObjectToPt] Processing element #" << i
|
|
|
- //<< ", key: " << obj.GetKey(i) << std::endl;
|
|
|
- if (i >= obj.size()) {
|
|
|
- std::cerr << "Index " << i << " out of range (size=" << obj.size() << ")" << std::endl;
|
|
|
- return false;
|
|
|
+bool ParseDataObjectToPt(ptree& pt, ResDataObject& obj) {
|
|
|
+ auto recursive_parse = [&](auto& self, ptree& current_pt, ResDataObject& current_obj, int depth) -> bool {
|
|
|
+ // 增强的空对象检查
|
|
|
+ if (!current_obj.IsObject() || current_obj.size() == 0) {
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- const char* key = obj.GetKey(i);
|
|
|
- if (!key || *key == '\0') { // 拒绝空指针或空字符串键
|
|
|
- std::cerr << "Invalid key at index " << i << std::endl;
|
|
|
+ if (depth > 100) { // 降低深度限制到更安全的100层
|
|
|
+ std::cerr << "Recursion depth limit exceeded (100)" << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- if (obj[i].size() > 0)
|
|
|
- {
|
|
|
- //object
|
|
|
- //std::cout << "[ParseDataObjectToPt] Element #" << i
|
|
|
- //<< " is a nested object, size: " << obj[i].size() << std::endl;
|
|
|
-
|
|
|
- ptree subpt;
|
|
|
- if (ParseDataObjectToPt(subpt, obj[i]) == false)
|
|
|
- {
|
|
|
- std::cerr << "[ParseDataObjectToPt] ERROR: Failed to parse nested object at index " << i << std::endl;
|
|
|
+ const size_t objSize = current_obj.size();
|
|
|
+ for (size_t i = 0; i < objSize; ++i) {
|
|
|
+ // 双重索引验证
|
|
|
+ if (i >= objSize || i >= current_obj.size()) {
|
|
|
+ std::cerr << "Index " << i << " out of range (size: "
|
|
|
+ << current_obj.size() << ")" << std::endl;
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- pt.add_child(obj.GetKey(i), subpt);
|
|
|
- //std::cout << "[ParseDataObjectToPt] Successfully added nested object with key: "
|
|
|
- //<< obj.GetKey(i) << std::endl;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- const char* value = static_cast<const char*>(obj[i]); // 明确类型转换
|
|
|
- if (!value) { // 处理空指针(使用空字符串替代)
|
|
|
- pt.add(key, "");
|
|
|
- }
|
|
|
- else {
|
|
|
- // 4. 检查字符串终止符(防止越界读取)
|
|
|
- size_t strLen = 0;
|
|
|
- while (strLen < 1024 * 1024 && value[strLen] != '\0') { // 限制最大长度
|
|
|
- strLen++;
|
|
|
+ try {
|
|
|
+ const char* key = current_obj.GetKey(i);
|
|
|
+ if (!key || *key == '\0') {
|
|
|
+ std::cerr << "Depth " << depth << ": Invalid key at index " << i
|
|
|
+ << " (size: " << current_obj.size() << ")" << std::endl;
|
|
|
+
|
|
|
+ // 跳过无效键而不是中止整个解析
|
|
|
+ continue;
|
|
|
}
|
|
|
- if (strLen >= 1024 * 1024) { // 超长字符串可能是无效数据
|
|
|
- std::cerr << "Value too long (key=" << key << ")" << std::endl;
|
|
|
- return false;
|
|
|
+
|
|
|
+ ResDataObject& child = current_obj[i];
|
|
|
+
|
|
|
+ // 更健壮的类型检查
|
|
|
+ if (child.IsObject() && child.size() > 0) {
|
|
|
+ ptree subpt;
|
|
|
+ if (!self(self, subpt, child, depth + 1)) {
|
|
|
+ std::cerr << "Depth " << depth << ": Failed parsing nested object '"
|
|
|
+ << key << "' (size: " << child.size() << ")" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ current_pt.add_child(key, subpt);
|
|
|
}
|
|
|
- pt.add(key, value);
|
|
|
+ else {
|
|
|
+ try {
|
|
|
+ // 安全的类型转换
|
|
|
+ const char* value = static_cast<const char*>(child);
|
|
|
+ current_pt.put(key, value ? value : "");
|
|
|
+ }
|
|
|
+ catch (...) {
|
|
|
+ current_pt.put(key, "");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (const ResDataObjectExption& e) {
|
|
|
+ std::cerr << "Depth " << depth << ": Exception at index " << i
|
|
|
+ << ": " << e.what() << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ catch (const std::exception& e) {
|
|
|
+ std::cerr << "Depth " << depth << ": Std exception at index " << i
|
|
|
+ << ": " << e.what() << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ catch (...) {
|
|
|
+ std::cerr << "Depth " << depth << ": Unknown exception at index " << i << std::endl;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ return true;
|
|
|
+ };
|
|
|
|
|
|
- //std::cout << "[ParseDataObjectToPt] Exiting function successfully" << std::endl;
|
|
|
- return true;
|
|
|
+ // 初始调用添加保护
|
|
|
+ try {
|
|
|
+ return recursive_parse(recursive_parse, pt, obj, 0);
|
|
|
+ }
|
|
|
+ catch (...) {
|
|
|
+ std::cerr << "Top-level exception in ParseDataObjectToPt" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
ResDataObjectExption::ResDataObjectExption(const char *pExp) : m_ExpContext(std::make_unique<std::string>(pExp ? pExp : "")) {}
|
|
@@ -288,7 +308,7 @@ ResDataObjectExption::ResDataObjectExption(const ResDataObjectExption &tValue) :
|
|
|
|
|
|
ResDataObjectExption::~ResDataObjectExption(void) = default;
|
|
|
|
|
|
-const char *ResDataObjectExption::what()
|
|
|
+const char *ResDataObjectExption::what() const
|
|
|
{
|
|
|
if(m_ExpContext->size() == 0)
|
|
|
{
|
|
@@ -326,6 +346,23 @@ ResDataObject_Pair& ResDataObject_Pair::operator=(const ResDataObject_Pair& othe
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
+ResDataObject_Pair& ResDataObject_Pair::operator=(ResDataObject_Pair&& other) noexcept
|
|
|
+{
|
|
|
+ if (this != &other) {
|
|
|
+ first = std::move(other.first);
|
|
|
+ second = std::move(other.second);
|
|
|
+
|
|
|
+ // 确保源对象处于有效状态(与移动构造逻辑一致)
|
|
|
+ if (!other.first) {
|
|
|
+ other.first = std::make_unique<std::string>();
|
|
|
+ }
|
|
|
+ if (!other.second) {
|
|
|
+ other.second = std::make_unique<ResDataObject>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
ResDataObject::ResDataObject(void) :
|
|
|
m_encode(std::make_unique<std::string>()),
|
|
|
m_value(std::make_unique<std::string>()),
|
|
@@ -336,11 +373,12 @@ ResDataObject::ResDataObject(const ResDataObject& tValue)
|
|
|
m_value(std::make_unique<std::string>(*tValue.m_value)),
|
|
|
m_vec(std::make_unique<std::vector<ResDataObject_Pair>>())
|
|
|
{
|
|
|
-
|
|
|
m_vec->reserve(tValue.m_vec->size());
|
|
|
for (const auto& pair : *tValue.m_vec) {
|
|
|
m_vec->push_back(pair);
|
|
|
}
|
|
|
+ //std::cerr << "[ResDataObject] Copied to " << this
|
|
|
+ //<< ", m_vec=" << m_vec.get() << std::endl;
|
|
|
}
|
|
|
|
|
|
ResDataObject::ResDataObject(ResDataObject&& tValue) noexcept
|
|
@@ -351,6 +389,12 @@ ResDataObject::ResDataObject(ResDataObject&& tValue) noexcept
|
|
|
tValue.m_encode = std::make_unique<std::string>();
|
|
|
tValue.m_value = std::make_unique<std::string>();
|
|
|
tValue.m_vec = std::make_unique<std::vector<ResDataObject_Pair>>();
|
|
|
+ //std::cerr << "[ResDataObject] move to " << this
|
|
|
+ //<< ", m_vec=" << m_vec.get() << std::endl;
|
|
|
+}
|
|
|
+
|
|
|
+ResDataObject::~ResDataObject(void)
|
|
|
+{
|
|
|
}
|
|
|
|
|
|
ResDataObject& ResDataObject::operator=(ResDataObject&& tValue) noexcept {
|
|
@@ -359,6 +403,10 @@ ResDataObject& ResDataObject::operator=(ResDataObject&& tValue) noexcept {
|
|
|
m_value = std::move(tValue.m_value);
|
|
|
m_vec = std::move(tValue.m_vec);
|
|
|
}
|
|
|
+
|
|
|
+ if (!tValue.m_vec) {
|
|
|
+ tValue.m_vec = std::make_unique<std::vector<ResDataObject_Pair>>();
|
|
|
+ }
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
@@ -371,12 +419,8 @@ void ResDataObject::clear()
|
|
|
m_vec->clear();
|
|
|
}
|
|
|
|
|
|
-size_t ResDataObject::size()
|
|
|
-{
|
|
|
- if (m_vec) {
|
|
|
- return m_vec->size();
|
|
|
- }
|
|
|
- return 0; // m_vec为空时返回0
|
|
|
+size_t ResDataObject::size() {
|
|
|
+ return m_vec->size();
|
|
|
}
|
|
|
|
|
|
bool ResDataObject::IsObject()
|
|
@@ -389,8 +433,8 @@ const char *ResDataObject::encode()
|
|
|
if (m_vec->empty() && !m_value->empty()) {
|
|
|
return m_value->c_str();
|
|
|
}
|
|
|
- ptree pt;
|
|
|
|
|
|
+ boost::property_tree::ptree pt;
|
|
|
if(ParseDataObjectToPt(pt,(*this)) == true)
|
|
|
{
|
|
|
std::stringstream strm;
|
|
@@ -400,8 +444,6 @@ const char *ResDataObject::encode()
|
|
|
}
|
|
|
|
|
|
throw ResDataObjectExption("encode failed. ");
|
|
|
-
|
|
|
- return NULL;
|
|
|
}
|
|
|
|
|
|
bool ResDataObject::decode( const char *pdata )
|
|
@@ -671,8 +713,12 @@ void ResDataObject::MakeKeyLower()
|
|
|
ResDataObject& ResDataObject::operator = (const char* pVal)
|
|
|
{
|
|
|
clear();
|
|
|
-
|
|
|
- (*m_value) = (pVal);
|
|
|
+ if (!pVal || reinterpret_cast<uintptr_t>(pVal) < 0x1000) { // 0x1000是常见的用户态有效内存起始阈值
|
|
|
+ *m_value = ""; // 用空字符串替代无效指针
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ *m_value = pVal; // 仅在指针有效时赋值
|
|
|
+ }
|
|
|
return (*this);
|
|
|
};
|
|
|
|
|
@@ -696,7 +742,6 @@ ResDataObject &ResDataObject::operator [](int idx)
|
|
|
if(idx < 0)
|
|
|
{
|
|
|
throw ResDataObjectExption("using minus idx to operate []");
|
|
|
- return (*this);
|
|
|
}
|
|
|
|
|
|
size_t idx_local = (size_t)idx;
|
|
@@ -742,7 +787,6 @@ const char* ResDataObject::GetKey(int idx)
|
|
|
if(idx < 0)
|
|
|
{
|
|
|
throw ResDataObjectExption("try to get key with minus idx");
|
|
|
- return (*this);
|
|
|
}
|
|
|
|
|
|
size_t idx_local = (size_t)idx;
|
|
@@ -994,7 +1038,11 @@ ResDataObject::operator double()
|
|
|
|
|
|
ResDataObject::operator const char*()
|
|
|
{
|
|
|
- return m_value->c_str();
|
|
|
+ if (!m_value) {
|
|
|
+ std::cerr << "[ResDataObject] operator const char*: m_value is null" << std::endl;
|
|
|
+ return ""; // 返回空字符串避免崩溃
|
|
|
+ }
|
|
|
+ return (*m_value).c_str();
|
|
|
};
|
|
|
|
|
|
|
|
@@ -1084,10 +1132,9 @@ int ResDataObject::GetNextOf(const char *pKey,int PrevIdx)
|
|
|
//erase
|
|
|
bool ResDataObject::eraseAllOf(const char *pKey)
|
|
|
{
|
|
|
- if(pKey == NULL)
|
|
|
- {
|
|
|
- clear();
|
|
|
- return true;
|
|
|
+ if (pKey == NULL) {
|
|
|
+ throw ResDataObjectExption("eraseAllOf: pKey cannot be NULL");
|
|
|
+ return false;
|
|
|
}
|
|
|
std::string keyname = (pKey);
|
|
|
//keyname = CCommonFun::MAKELOWER(keyname);
|
|
@@ -1313,7 +1360,7 @@ ResDataObject& ResDataObject::operator = (const double tValue)
|
|
|
|
|
|
//新方案(丢精度)
|
|
|
char szStr[64];
|
|
|
- snprintf(szStr, sizeof(szStr), "%.6f", tValue);
|
|
|
+ snprintf(szStr, sizeof(szStr), "%.17g", tValue);
|
|
|
|
|
|
strm << szStr;
|
|
|
(*this) = strm.str().c_str();
|
|
@@ -1429,27 +1476,39 @@ bool ResDataObject::add(const char* pKey,double tValue)
|
|
|
bool ResDataObject::add(const char* pKey,const char* pValue)
|
|
|
{
|
|
|
ResDataObject obj;
|
|
|
- obj = pValue;
|
|
|
+ if (!pValue || reinterpret_cast<uintptr_t>(pValue) < 0x1000) {
|
|
|
+ obj = ""; // 无效值用空字符串替代
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ obj = pValue;
|
|
|
+ }
|
|
|
return add(pKey,obj);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
bool ResDataObject::add(const char* pKey,ResDataObject &dataobj)
|
|
|
{
|
|
|
+ if (!m_vec) {
|
|
|
+ std::cerr << "Error: m_vec is null in ResDataObject::add" << std::endl;
|
|
|
+ m_vec = std::make_unique<std::vector<ResDataObject_Pair>>();
|
|
|
+ }
|
|
|
+
|
|
|
if (!pKey) pKey = ""; // 处理空指针
|
|
|
|
|
|
- ResDataObject_Pair new_pair;
|
|
|
- *new_pair.first = pKey; // 安全赋值
|
|
|
|
|
|
- // 深拷贝dataobj
|
|
|
- *new_pair.second = dataobj;
|
|
|
+ try {
|
|
|
|
|
|
- m_vec->push_back(std::move(new_pair));
|
|
|
- return true;
|
|
|
+ m_vec->emplace_back();
|
|
|
+ auto& new_pair = m_vec->back();
|
|
|
+ *new_pair.first = pKey;
|
|
|
+ *new_pair.second = dataobj;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ catch (...) {
|
|
|
+ std::cerr << "[add] vector@" << m_vec.get() << " is invalid (memory corrupted)" << std::endl;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-
|
|
|
-
|
|
|
bool ResDataObject::update(const char* pKey,bool tValue)
|
|
|
{
|
|
|
eraseAllOf(pKey);
|