From 4b4d792c9202f0825fa758cf77661b3ad0fb5725 Mon Sep 17 00:00:00 2001 From: msojocs Date: Fri, 30 Jun 2023 17:43:28 +0800 Subject: [PATCH] fix: Parser::DOM --- src/include/wxml.h | 7 +----- src/wxml/compiler.cpp | 6 ++--- src/wxml/dom_lib/parser.cpp | 27 +++++++-------------- src/wxml/dom_lib/wxml_dom.cpp | 24 +++++++++++-------- test/wcc.disassembly.cpp | 45 +++++++++++++++++++++++++++-------- 5 files changed, 62 insertions(+), 47 deletions(-) diff --git a/src/include/wxml.h b/src/include/wxml.h index 5f605c3..771d96a 100644 --- a/src/include/wxml.h +++ b/src/include/wxml.h @@ -242,7 +242,7 @@ namespace WXML int componentCnt = 0; public: std::string offset_0; // type - std::map offset_12; + // std::map offset_12; std::string offset_24; // ??? std::map offset_48; std::vector> offset_72; // @@ -329,11 +329,6 @@ namespace WXML std::shared_ptr dom; // offset_4 ? int offset_4 = 0; std::deque dequeStr;// offset_8 - int offset_16 = 0; - int offset_32 = 0; // _DWORD * a1[8] - int offset_36 = 0; // - int offset_40 = 0; - int offset_44 = 0; std::deque> dequeDom; // offset_48 int a1 + 48, _DWORD * a1 + 12 std::vector tokenList; // offset_88 int peekIndex = 0; // offset_100 diff --git a/src/wxml/compiler.cpp b/src/wxml/compiler.cpp index 5442c3c..89a00c4 100644 --- a/src/wxml/compiler.cpp +++ b/src/wxml/compiler.cpp @@ -391,8 +391,8 @@ namespace WXML{ { if (a1 == "template") { - auto it = a1.offset_12.find("name"); - if (it != a1.offset_12.end()) + auto it = a1.offset_48.find("name"); + if (it != a1.offset_48.end()) { a1.offset_0.replace(0, a1.offset_0.size(), "wx-define", 9u); } @@ -400,7 +400,7 @@ namespace WXML{ if (a1 == "wx-define") { WXML::NameAllocator na(a17, a18); - auto token = a1.offset_12["name"]; + auto token = a1.offset_48["name"]; auto attr = token.ToAttrContent(); a3[attr].assign(a2); a1.RenderMeAsFunction( diff --git a/src/wxml/dom_lib/parser.cpp b/src/wxml/dom_lib/parser.cpp index e7b72b4..8a8d110 100644 --- a/src/wxml/dom_lib/parser.cpp +++ b/src/wxml/dom_lib/parser.cpp @@ -131,14 +131,7 @@ namespace WXML throw this->Error("unexpected tag", 0); } this->peekIndex++; - if (this->offset_32 == this->offset_40 - 24) - { - this->dequeStr.push_back(tag); - } - else - { - this->offset_32 += 24; // 0x18h - } + this->dequeStr.push_back(tag); std::shared_ptr domPtr(new WXML::DOMLib::WXMLDom()); domPtr->offset_0.assign(tag); domPtr->offset_24.assign(domPtr->offset_0); @@ -160,22 +153,20 @@ namespace WXML if (/*v48[5] || */!v11.IsMatch("Error("unexpected token", &token); - throw "ParseException"; + throw err; } this->peekIndex++; auto v47 = this->Peek(); - auto v13 = this->offset_32; std::string v40 = ""; - if (this->offset_16 == v13) + if (this->dequeStr.begin() == this->dequeStr.end()) { - + v40 = ""; } else { - // if (v13 == this->offset_36) - // v13 = this->offset_44 - v40 = ""; + v40 = *this->dequeStr.end(); } + if (!v47.IsMatch(&v40[0])) { std::string msg = "expect end-tag `" + v40; @@ -206,7 +197,7 @@ namespace WXML } if (token.IsMatch("offset_32 == this->offset_16) + if (this->dequeStr.begin() == this->dequeStr.end()) { throw this->Error("get tag end without start", 0); } @@ -225,7 +216,7 @@ namespace WXML if (v19 > 0x17u || ((0x800013u >> v19) & 1) == 0) { auto v45 = this->dequeDom.back(); - std::shared_ptr dom; + std::shared_ptr dom(new WXML::DOMLib::WXMLDom()); dom->offset_0 = "TEXTNODE"; dom->offset_84 = token; v45->offset_72.push_back(dom); @@ -258,7 +249,7 @@ namespace WXML break; if (token.IsMatch("offset_4 == this->offset_32) + if (this->dequeStr.begin() == this->dequeStr.end()) { throw WXML::DOMLib::Parser::Error("get tag end without start", nullptr); } diff --git a/src/wxml/dom_lib/wxml_dom.cpp b/src/wxml/dom_lib/wxml_dom.cpp index 6feec33..219add4 100644 --- a/src/wxml/dom_lib/wxml_dom.cpp +++ b/src/wxml/dom_lib/wxml_dom.cpp @@ -649,10 +649,10 @@ namespace WXML { if(this->offset_0 == "import" || this->offset_0 == "include") { std::string v13 = "src"; - int v8 = this->offset_12.count(v13); + int v8 = this->offset_48.count(v13); if (v8) { - std::string attr = this->offset_12[v13].ToAttrContent(); + std::string attr = this->offset_48[v13].ToAttrContent(); } } @@ -820,34 +820,38 @@ namespace WXML { // *v4 << this->offset_84; } } + + /** + * TODO + */ bool WXMLDom::IfHasItsElse( int a2, std::vector const& a3 ) { bool hasElIf = true; - if (this->offset_12.count("wx:else") != 0) + if (this->offset_72[a2]->offset_48.count("wx:else") != 0) { - hasElIf = this->offset_12.count("wx:elif"); + hasElIf = this->offset_72[a2]->offset_48.count("wx:elif"); } if (hasElIf) return true; bool hasIf = false; - if (this->offset_12.count("wx:if") != 0) + if (this->offset_72[a2]->offset_48.count("wx:if") != 0) { - hasIf = this->offset_12.count("wx-if") == 0; + hasIf = this->offset_72[a2]->offset_48.count("wx-if") == 0; } if (!hasIf) { int v7 = a2 - 1; - if(this->offset_12.begin() == this->offset_12.end()) + if(this->offset_48.begin() == this->offset_48.end()) { - for (int i = a2 + 1; i < this->offset_12.size(); i++) + for (int i = a2 + 1; i < this->offset_48.size(); i++) { bool hasElIf = true; - if(!this->offset_12.count("wx:else")) + if(!this->offset_48.count("wx:else")) { - hasElIf = this->offset_12.count("wx:elif"); + hasElIf = this->offset_48.count("wx:elif"); } if (!hasElIf) { diff --git a/test/wcc.disassembly.cpp b/test/wcc.disassembly.cpp index 42dd261..3c0e66a 100644 --- a/test/wcc.disassembly.cpp +++ b/test/wcc.disassembly.cpp @@ -23027,6 +23027,7 @@ void __usercall WXML::DOMLib::Parser::DOM(_DWORD *a1@, WXML::DOMLib::Parser } else { + // "<" if ( WXML::DOMLib::Token::IsMatch((int)v43, (WXML::DOMLib::Token *)&unk_5539CC, v22) ) { ++a1[25]; @@ -23049,13 +23050,17 @@ void __usercall WXML::DOMLib::Parser::DOM(_DWORD *a1@, WXML::DOMLib::Parser // offset_32 v6 = (char *)a1[8]; v35 = a1 + 2; // offset_8 + // v6 offset_32; a1[10] offset_40 if ( v6 == (char *)(a1[10] - 24) ) { + // 重新分配空间,CPP内部方法 std::deque::_M_push_back_aux((int)v35, (int)v5); } else { + // 把v5填进v6(offset_32) std::string::basic_string(v6, (int)v5); + // v6(offset_32)指针后移 a1[8] += 24; } Blocka = operator new(0x128u); @@ -23100,15 +23105,19 @@ void __usercall WXML::DOMLib::Parser::DOM(_DWORD *a1@, WXML::DOMLib::Parser ++a1[25]; v12 = WXML::DOMLib::Parser::Peek(a1); WXML::DOMLib::Token::operator=((int)&v47, (int)v12); - v13 = a1[8]; - if ( a1[4] == v13 ) + v13 = a1[8]; // a1.offset_32 end + // a1.offset_16 start + if ( a1[4] == v13 ) // start == end { std::string::basic_string((void **)v40, (char *)&byte_5537CA); } else { + // v13 end + // offset_36 if ( v13 == a1[9] ) - v13 = *(_DWORD *)(a1[11] - 4) + 504; + // + v13 = *(_DWORD *)(a1[11] - 4) + 504; // 504 / 24 = 21 std::string::basic_string((char *)v40, v13 - 24); } if ( !WXML::DOMLib::Token::IsMatch((int)&v47, v40[0], v27) ) @@ -23162,6 +23171,7 @@ LABEL_27: } if ( WXML::DOMLib::Token::IsMatch((int)v43, (WXML::DOMLib::Token *)", WXML: break; if ( WXML::DOMLib::Token::IsMatch((int)v7, (WXML::DOMLib::Token *)"( std::__shared_count<(__gnu_cxx::_Lock_policy)2>::operator=((volatile signed __int32 **)(a1 + 4), (int)v14); std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v14); std::string::operator=(*(unsigned int **)a1, "root"); + // a1 + 48 => a1.offset_48 std::deque>::push_back(a1 + 48, (_DWORD *)a1); WXML::DOMLib::Parser::DOMS((WXML::DOMLib::Parser *)a1, a2); } @@ -27113,9 +27125,9 @@ LABEL_12: // this v31 = lpuexcpt; - // offset_0 + 1 + // offset_0 + 1 lineCount v32 = *(_DWORD *)lpuexcpt + 1; - // offset_12 + 1 + // offset_12 + 1 lineLength v33 = *((_DWORD *)lpuexcpt + 3) + 1; v16 = _bittest(&v46, 0x12u); *(_DWORD *)lpuexcpt = v32; @@ -27129,33 +27141,40 @@ LABEL_12: v65 = v67; // offset_16 v35 = *((_DWORD *)v31 + 4); + // offset_0 v49 = 0; + // offset_8 = this->offset_16 v51 = v35; // offset_20 v36 = *((_DWORD *)v31 + 5); + // offset_4 v50 = 0; + // token.offset_12 = this->offset_20 v52 = v36; - // offset_4 + // this.offset_4 v37 = *((_DWORD *)v31 + 1); - // offset_4 + // this.offset_4 = this.offset_4 + 1 *((_DWORD *)v31 + 1) = v32; - // offset_8 + // this.offset_8 v38 = *((_DWORD *)v31 + 2); - // offset_20 + // this.offset_20 = this.offset_12(lineLength) *((_DWORD *)v31 + 5) = v33; - // offset_16 + // this.offset_16 = this.offset_8(lineCount) *((_DWORD *)v31 + 4) = v38; v58 = 0; v39 = WXML::DOMLib::Machine::STT[v45]; v59[0] = 0; v62 = 0; + // token.offset_24 v55 = v39; v63[0] = 0; v66 = 0; v56 = 0; v64 = 0; v60 = -1; + // offset_16 = this->offset_4 v53 = v37; + // offset_20 = - this->offset_4 v54 = v34 - v37; if ( v39 == 3 ) v40 = a5; @@ -52657,6 +52676,7 @@ char __thiscall WXML::DOMLib::WXMLDom::IfHasItsElse(_DWORD *this, signed int a2, void *v23[6]; // [esp+60h] [ebp-38h] BYREF void *v24[8]; // [esp+78h] [ebp-20h] BYREF + // this[18] -> this->offset_72 v17 = (_DWORD *)(*(_DWORD *)(this[18] + 8 * a2) + 48); std::string::basic_string(v23, "wx:else"); v3 = std::map::count(v17, (int)v23); @@ -52677,6 +52697,9 @@ char __thiscall WXML::DOMLib::WXMLDom::IfHasItsElse(_DWORD *this, signed int a2, v14 = 0; if ( !v4 ) { + // _DWORD *this, + // this[18] -> this.offset_(18 * 4) -> this->offset_72 + // a2 是 int,那么8可能是单位数据的大小 v15 = (_DWORD *)(*(_DWORD *)(this[18] + 8 * a2) + 48); std::string::basic_string(v24, "wx-if"); v14 = !std::map::count(v15, (int)v24); @@ -52694,6 +52717,8 @@ char __thiscall WXML::DOMLib::WXMLDom::IfHasItsElse(_DWORD *this, signed int a2, v16 = i; v7 = this[18]; // (this[19] - v7) / 8 + // 8 是单位大小,除以8就是单位的数量 + // this[18]是起点,this[19]是终点 if ( (this[19] - v7) >> 3 <= i ) break; v10 = 8 * i;