X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14d36de822b56374abeac03d4d7354784b6bb955..f81dc6e93170cb73c6d614b77e26be49baa724d2:/src/html/htmltag.cpp diff --git a/src/html/htmltag.cpp b/src/html/htmltag.cpp index 8848884e57..98a1ff4fba 100644 --- a/src/html/htmltag.cpp +++ b/src/html/htmltag.cpp @@ -4,20 +4,15 @@ // Author: Vaclav Slavik // RCS-ID: $Id$ // Copyright: (c) 1999 Vaclav Slavik -// Licence: wxWindows Licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - -#ifdef __GNUG__ -#pragma implementation -#endif - #include "wx/wxprec.h" #include "wx/defs.h" #if wxUSE_HTML -#ifdef __BORDLANDC__ +#ifdef __BORLANDC__ #pragma hdrstop #endif @@ -57,10 +52,15 @@ IMPLEMENT_CLASS(wxHtmlTagsCache,wxObject) #define CACHE_INCREMENT 64 +bool wxIsCDATAElement(const wxChar *tag) +{ + return (wxStrcmp(tag, _T("SCRIPT")) == 0) || + (wxStrcmp(tag, _T("STYLE")) == 0); +} + wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source) { const wxChar *src = source.c_str(); - int tg, stpos; int lng = source.Length(); wxChar tagBuffer[256]; @@ -75,16 +75,17 @@ wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source) { if (m_CacheSize % CACHE_INCREMENT == 0) m_Cache = (wxHtmlCacheItem*) realloc(m_Cache, (m_CacheSize + CACHE_INCREMENT) * sizeof(wxHtmlCacheItem)); - tg = m_CacheSize++; - m_Cache[tg].Key = stpos = pos++; + int tg = m_CacheSize++; + int stpos = pos++; + m_Cache[tg].Key = stpos; - size_t i; + int i; for ( i = 0; - pos < lng && i < WXSIZEOF(tagBuffer) - 1 && + pos < lng && i < (int)WXSIZEOF(tagBuffer) - 1 && src[pos] != wxT('>') && !wxIsspace(src[pos]); i++, pos++ ) { - tagBuffer[i] = wxToupper(src[pos]); + tagBuffer[i] = (wxChar)wxToupper(src[pos]); } tagBuffer[i] = _T('\0'); @@ -108,6 +109,64 @@ wxHtmlTagsCache::wxHtmlTagsCache(const wxString& source) else { m_Cache[tg].End1 = m_Cache[tg].End2 = -1; + + if (wxIsCDATAElement(tagBuffer)) + { + // store the orig pos in case we are missing the closing + // tag (see below) + wxInt32 old_pos = pos; + bool foundCloseTag = false; + + // find next matching tag + int tag_len = wxStrlen(tagBuffer); + while (pos < lng) + { + // find the ending tag + while (pos + 1 < lng && + (src[pos] != '<' || src[pos+1] != '/')) + ++pos; + if (src[pos] == '<') + ++pos; + + // see if it matches + int match_pos = 0; + while (pos < lng && match_pos < tag_len && src[pos] != '>' && src[pos] != '<') { + // cast to wxChar needed to suppress warning in + // Unicode build + if ((wxChar)wxToupper(src[pos]) == tagBuffer[match_pos]) { + ++match_pos; + } + else if (src[pos] == wxT(' ') || src[pos] == wxT('\n') || + src[pos] == wxT('\r') || src[pos] == wxT('\t')) { + // need to skip over these + } + else { + match_pos = 0; + } + ++pos; + } + + // found a match + if (match_pos == tag_len) + { + pos = pos - tag_len - 3; + foundCloseTag = true; + break; + } + else // keep looking for the closing tag + { + ++pos; + } + } + if (!foundCloseTag) + { + // we didn't find closing tag; this means the markup + // is incorrect and the best thing we can do is to + // ignore the unclosed tag and continue parsing as if + // it didn't exist: + pos = old_pos; + } + } } } @@ -130,6 +189,16 @@ void wxHtmlTagsCache::QueryTag(int at, int* end1, int* end2) int delta = (at < m_Cache[m_CachePos].Key) ? -1 : 1; do { + if ( m_CachePos < 0 || m_CachePos == m_CacheSize ) + { + // something is very wrong with HTML, give up by returning an + // impossibly large value which is going to be ignored by the + // caller + *end1 = + *end2 = INT_MAX; + return; + } + m_CachePos += delta; } while (m_Cache[m_CachePos].Key != at); @@ -291,12 +360,12 @@ wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, } #undef IS_WHITE - } - m_Begin = i; + } + m_Begin = i; - cache->QueryTag(pos, &m_End1, &m_End2); - if (m_End1 > end_pos) m_End1 = end_pos; - if (m_End2 > end_pos) m_End2 = end_pos; + cache->QueryTag(pos, &m_End1, &m_End2); + if (m_End1 > end_pos) m_End1 = end_pos; + if (m_End2 > end_pos) m_End2 = end_pos; } wxHtmlTag::~wxHtmlTag() @@ -313,12 +382,12 @@ wxHtmlTag::~wxHtmlTag() bool wxHtmlTag::HasParam(const wxString& par) const { - return (m_ParamNames.Index(par, FALSE) != wxNOT_FOUND); + return (m_ParamNames.Index(par, false) != wxNOT_FOUND); } wxString wxHtmlTag::GetParam(const wxString& par, bool with_commas) const { - int index = m_ParamNames.Index(par, FALSE); + int index = m_ParamNames.Index(par, false); if (index == wxNOT_FOUND) return wxEmptyString; if (with_commas) @@ -344,23 +413,23 @@ bool wxHtmlTag::GetParamAsColour(const wxString& par, wxColour *clr) const { wxString str = GetParam(par); - if (str.IsEmpty()) return FALSE; + if (str.empty()) return false; if (str.GetChar(0) == wxT('#')) { unsigned long tmp; if (ScanParam(par, wxT("#%lX"), &tmp) != 1) - return FALSE; + return false; *clr = wxColour((unsigned char)((tmp & 0xFF0000) >> 16), - (unsigned char)((tmp & 0x00FF00) >> 8), - (unsigned char)(tmp & 0x0000FF)); - return TRUE; + (unsigned char)((tmp & 0x00FF00) >> 8), + (unsigned char)(tmp & 0x0000FF)); + return true; } else { // Handle colours defined in HTML 4.0: #define HTML_COLOUR(name,r,g,b) \ - if (str.IsSameAs(wxT(name), FALSE)) \ - { *clr = wxColour(r,g,b); return TRUE; } + if (str.IsSameAs(wxT(name), false)) \ + { *clr = wxColour(r,g,b); return true; } HTML_COLOUR("black", 0x00,0x00,0x00) HTML_COLOUR("silver", 0xC0,0xC0,0xC0) HTML_COLOUR("gray", 0x80,0x80,0x80) @@ -380,12 +449,12 @@ bool wxHtmlTag::GetParamAsColour(const wxString& par, wxColour *clr) const #undef HTML_COLOUR } - return FALSE; + return false; } bool wxHtmlTag::GetParamAsInt(const wxString& par, int *clr) const { - if (!HasParam(par)) return FALSE; + if (!HasParam(par)) return false; long i; bool succ = GetParam(par).ToLong(&i); *clr = (int)i; @@ -394,7 +463,7 @@ bool wxHtmlTag::GetParamAsInt(const wxString& par, int *clr) const wxString wxHtmlTag::GetAllParams() const { - // VS: this function is for backward compatiblity only, + // VS: this function is for backward compatibility only, // never used by wxHTML wxString s; size_t cnt = m_ParamNames.GetCount();