diff --git a/main/starmath/source/smdetect.cxx b/main/starmath/source/smdetect.cxx index d750344..c08fc07 100644 --- a/main/starmath/source/smdetect.cxx +++ b/main/starmath/source/smdetect.cxx @@ -74,7 +74,6 @@ #include "document.hxx" #include "eqnolefilehdr.hxx" - using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::io; @@ -307,9 +306,7 @@ SmFilterDetect::~SmFilterDetect() } else { - //Test to see if this begins with xml and if so run it through - //the MathML filter. There are all sorts of things wrong with - //this approach, to be fixed at a better level than here + // DesignScience Equation Editor MathType 3.0 SvStream *pStrm = aMedium.GetInStream(); aTypeName.Erase(); if (pStrm && !pStrm->GetError()) @@ -326,64 +323,75 @@ SmFilterDetect::~SmFilterDetect() } else { - // #124636# detection should not only check for xml, but at least also for - // the math start element and the MathML URL. Additionally take their order - // into account. Also allow the case where the start element has a namespace - // (e.g. Seek( STREAM_SEEK_TO_BEGIN ); - const sal_uLong nBytesRead(pStrm->Read( aBuffer, nReadSize )); - - if(nBytesRead > (5 + 1 + 34 + 5)) // xml + '>' + URL + '(<|:)math' + const size_t nBufSize=2048; + sal_uInt16 aBuffer[nBufSize]; // will be casted to an Unicode-Array below + sal_uInt8* pByte = reinterpret_cast(aBuffer); + const sal_uLong nBytesRead(pStrm->Read( pByte, nBufSize * 2 ) ); + const sal_uLong nUnicodeCharsRead (nBytesRead / 2 ); + + // For backwards searching an OUString is used. The conversion needs an + // encoding information. Default endocing is UTF-8, UTF-16 is possible + // (e.g. from MS "Math Input Control"), others are unlikely. + // Looking for Byte Order Mark + rtl_TextEncoding eEncoding = RTL_TEXTENCODING_UTF8; + bool bIsUnicode = false; + if (nBytesRead >= 2 && (aBuffer[0]==0xfffe || aBuffer[0]==0xfeff) ) { - // end string with null - aBuffer[nBytesRead + 1] = 0; - - // is it a xml file? - const sal_Char* pXML = strstr(aBuffer, " 56) // minimal length of 'math' element incl. namespace URL in UTF-8 + { + const sal_Char* pChar = reinterpret_cast(aBuffer); + sal_Unicode* pUnicode = (sal_Unicode*) aBuffer; + + OUString sFragment( (bIsUnicode) ? + OUString( pUnicode , nUnicodeCharsRead ) + : OUString( pChar, nBytesRead, eEncoding) ); + + // look for MathML URL + OUString sURL( OUString::createFromAscii("http://www.w3.org/1998/Math/MathML")); + sal_Int32 nPosURL; + nPosURL = sFragment.indexOf(sURL); + if (nPosURL >= 0) { - // does it have the MathML URL? - const sal_Char* pURL = strstr(aBuffer, "http://www.w3.org/1998/Math/MathML"); - - // URL has to be after XML start - if(pURL && pURL > pXML) + // The URL has to be value of an xmlns attribute + sal_Int32 nPosEQ; + nPosEQ = sFragment.lastIndexOf(OUString::createFromAscii("="),nPosURL); + if (nPosEQ >= 0) { - // look if we have a direct math start element - sal_Char* pMathStart = strstr(aBuffer, "= 0) { - // if not, look if we have a math start element in another namespace - pMathStart = strstr(aBuffer, ":math"); - - if(pMathStart) + // a prefix might be defined + OUString sPrefix = (sFragment.copy(nPosXMLNS+5,nPosEQ-(nPosXMLNS+5))).trim(); + // such prefix definition must start with colon (will be removed below) + bool bHasPrefix( (sPrefix.isEmpty()) ? false : sPrefix.toChar() == sal_Unicode(':') ); + + // now look for math element start '= 0) { - // if found, this has to be in front of the evtl. also existing namespace - // declaration also containing :math to be the start element - sal_Char* pNamespaceMath = strstr(aBuffer, "xmlns:math"); - - if(pNamespaceMath && pMathStart > pNamespaceMath) - { - // invalid :math found (probably part of the namespace declaration) - // -> this cannot be the math start element - pMathStart = 0; - } + isMathFile = true; } } - - // MathStart has to be before the URL - if(pMathStart && pMathStart < pURL) - { - isMathFile = true; - } } } - if(isMathFile) { static const sal_Char sFltrNm_2[] = MATHML_XML;