json解析導致的崩潰問題 cocos2.* 底層問題

bloodsuckerccj發表於2016-10-19

過程:

======



    m_dropMsg->push("歡迎來到德州遊戲的世界");
    m_dropMsg->push("<Root momoID=\"emVjSVQ2dkdBa0tYREI3N3ZteGtaZz09\"><p color=\"32,144,32\">[#%&#]:</p></Root>");

======

void DropMsg::push( const char* szMsg )
{
if (parse(szMsg) && m_configQueue.size() == 1)
{
start();
}
}

======

bool DropMsg::parse( const char* szMsg )
{
    DropConfig dropConfig = parseConfig(szMsg);
    CEmojiManager::shareEmojiManager()->pushNoitceList(dropConfig);
    if(!m_configQueue.empty() && m_configQueue.back() == dropConfig)
{
return false;
}
if (!dropConfig.textVec.empty())
{
m_configQueue.push(dropConfig);
}
return true;
}

======

DropConfig DropMsg::parseConfig( const char* szData )
{
tinyxml2::XMLDocument doc;
XMLError error = doc.Parse(szData);
DropConfig dropConfig;
if (error == XML_NO_ERROR)
{
tinyxml2::XMLElement* pRoot = doc.FirstChildElement("Root");
if (pRoot)
{
tinyxml2::XMLElement* pElemet = pRoot->FirstChildElement("p");
if (pRoot->Attribute("time"))
{
dropConfig.dt = CCString::create(pRoot->Attribute("time"))->floatValue();
}
if (pRoot->Attribute("momoID"))
{
const char* szMomoID = CCString::create(pRoot->Attribute("momoID"))->getCString();
int len = strlen(szMomoID);
memcpy(dropConfig.momoID,szMomoID,len);
}
while (pElemet)
{
DropText textFormat;


                if(!pElemet->GetText()){
                    
                    CCLog("FUCK NULL POINT");
                    textFormat.strText="";
                    textFormat.color =  ccc3(255,255,255);
                }else{
                    
                    textFormat.strText = pElemet->GetText();
                    
                    if (pElemet->Attribute("msg"))
                    {
                        textFormat.strText = pElemet->Attribute("msg");
                    }
                    
                    if (pElemet->Attribute("color"))
                    {
                        std::string strColor = pElemet->Attribute("color");
                        
                        std::vector<std::string> aStringResult;
                        StringTool::split(string(strColor.c_str()),string(","),aStringResult);
                        textFormat.color =  ccc3(CCString::create(aStringResult[0].c_str())->intValue(),CCString::create(aStringResult[1].c_str())->intValue(),CCString::create(aStringResult[2].c_str())->intValue());
                    }
                    if (pElemet->Attribute("size"))
                    {
                        textFormat.size = CCString::create(pElemet->Attribute("size"))->intValue();
                    }
                    
                    if(!textFormat.strText.empty())
                    {
                        dropConfig.textVec.push_back(textFormat);
                    }
                }
pElemet = pElemet->NextSiblingElement("p");
}
}
}else
{
DropText textFormat;
textFormat.strText = szData;
if (!textFormat.strText.empty())
{
dropConfig.textVec.push_back(textFormat);
}
}
return dropConfig;
}

======

const char* XMLElement::GetText() const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        return FirstChild()->ToText()->Value();
    }
    return 0;
}

=======

 const char* Value() const {
        return _value.GetStr();
    }

直接掛裡面================================

const char* StrPair::GetStr()
{
    if ( _flags & NEEDS_FLUSH ) {
        *_end = 0;
        _flags ^= NEEDS_FLUSH;
        if ( _flags ) {
            char* p = _start; // the read pointer
            char* q = _start; // the write pointer
            while( p < _end ) {
                if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) {
                    // CR-LF pair becomes LF
                    // CR alone becomes LF
                    // LF-CR becomes LF
                    if ( *(p+1) == LF ) {
                        p += 2;
                    }
                    else {
                        ++p;
                    }
                    *q++ = LF;
                }
                else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) {
                    if ( *(p+1) == CR ) {
                        p += 2;
                    }
                    else {
                        ++p;
                    }
                    *q++ = LF;
                }
                else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) {
                    // Entities handled by tinyXML2:
                    // - special entities in the entity table [in/out]
                    // - numeric character reference [in]
                    //   &#20013; or &#x4e2d;
                    if ( *(p+1) == '#' ) {
                        char buf[10] = { 0 };
                        int len;
                        p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) );//原因是因為進了這裡 &#**;轉義 進了“&#”找不到“;”
                       // if(!p)
                       // return "*";
                        for( int i=0; i<len; ++i ) {
                            *q++ = buf[i];
                        }
                        TIXMLASSERT( q <= p );//=================================================  拋異常掛掉
                    }
                    else {
                        int i=0;
                        for(; i<NUM_ENTITIES; ++i ) {
                            if (    strncmp( p+1, entities[i].pattern, entities[i].length ) == 0
                                    && *(p+entities[i].length+1) == ';' ) {
                                // Found an entity convert;
                                *q = entities[i].value;
                                ++q;
                                p += entities[i].length + 2;
                                break;
                            }
                        }
                        if ( i == NUM_ENTITIES ) {
                            // fixme: treat as error?
                            ++p;
                            ++q;
                        }
                    }
                }
                else {
                    *q = *p;
                    ++p;
                    ++q;
                }
            }
            *q = 0;
        }
        // The loop below has plenty going on, and this
        // is a less useful mode. Break it out.
        if ( _flags & COLLAPSE_WHITESPACE ) {
            CollapseWhitespace();
        }
        _flags = (_flags & NEEDS_DELETE);
    }
    return _start;
}

}

轉義處理:

{
    // Presume an entity, and pull it out.
    *length = 0;
    if ( *(p+1) == '#' && *(p+2) ) {
        unsigned long ucs = 0;
        ptrdiff_t delta = 0;
        unsigned mult = 1;
        if ( *(p+2) == 'x' ) {
            // Hexadecimal.
            if ( !*(p+3) ) {
                return 0;
            }
            const char* q = p+3;
            q = strchr( q, ';' );
            if ( !q || !*q ) {
                return 0;
            }
            delta = q-p;
            --q;
            while ( *q != 'x' ) {
                if ( *q >= '0' && *q <= '9' ) {
                    ucs += mult * (*q - '0');
                }
                else if ( *q >= 'a' && *q <= 'f' ) {
                    ucs += mult * (*q - 'a' + 10);
                }
                else if ( *q >= 'A' && *q <= 'F' ) {
                    ucs += mult * (*q - 'A' + 10 );
                }
                else {
                    return 0;
                }
                mult *= 16;
                --q;
            }
        }
        else {
            // Decimal.
            if ( !*(p+2) ) {
                return 0;
            }
            const char* q = p+2;
            q = strchr( q, ';' );
            if ( !q || !*q ) {
                return 0;
            }
            delta = q-p;
            --q;
            while ( *q != '#' ) {
                if ( *q >= '0' && *q <= '9' ) {
                    ucs += mult * (*q - '0');
                }
                else {
                    return 0;
                }
                mult *= 10;
                --q;
            }
        }
        // convert the UCS to UTF-8
        ConvertUTF32ToUTF8( ucs, value, length );
        return p + delta + 1;
    }
    return p+1;
}



相關文章