dtrans/Library_mcnttype.mk | 1 dtrans/source/cnttype/mcnttype.cxx | 270 ++----------------------------------- dtrans/source/cnttype/mcnttype.hxx | 3 svtools/source/misc/transfer.cxx | 48 +++--- 4 files changed, 42 insertions(+), 280 deletions(-)
New commits: commit 3bc8e2f3ab69adb9196508688e5211dc171add95 Author: Stephan Bergmann <[email protected]> AuthorDate: Thu Oct 11 17:51:32 2018 +0200 Commit: Stephan Bergmann <[email protected]> CommitDate: Thu Oct 11 20:38:59 2018 +0200 Revert "tdf#120158: fix ImplGetParameterString for typename" This reverts commit 40e22f1e1bd44a1aa56ff77b82f1306ed1076ebf. See the commit message of <https://gerrit.libreoffice.org/61684> "tdf#120158: Base CMimeContentType on INetMIME::scanContentType" why that change is considered a superior fix compared to the reverted one. Change-Id: I1a0d77edee5bb18a98890d2021c777bc4c148a26 Reviewed-on: https://gerrit.libreoffice.org/61686 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx index b7c2daf062ab..5600107f8eb4 100644 --- a/svtools/source/misc/transfer.cxx +++ b/svtools/source/misc/transfer.cxx @@ -104,25 +104,6 @@ SvStream& WriteTransferableObjectDescriptor( SvStream& rOStm, const Transferable return rOStm; } -// Clean OUString given in parameter -// by returning an other OUString containing only authorized chars -static OUString lcl_getAuthorizedCharsString(const OUString& rInputString) -{ - sal_Bool pToAccept[128]; - for (sal_Bool & rb : pToAccept) - rb = false; - - const char aQuotedParamChars[] = - "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. "; - - for ( sal_Int32 nInd = 0; nInd < RTL_CONSTASCII_LENGTH(aQuotedParamChars); ++nInd ) - { - sal_Unicode nChar = aQuotedParamChars[nInd]; - if ( nChar < 128 ) - pToAccept[nChar] = true; - } - return rtl::Uri::encode(rInputString, pToAccept, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8); -} // the reading of the parameter is done using the special service css::datatransfer::MimeContentType, // a similar approach should be implemented for creation of the mimetype string; @@ -140,14 +121,32 @@ static OUString ImplGetParameterString( const TransferableObjectDescriptor& rObj if( !rObjDesc.maTypeName.isEmpty() ) { - // the type name might contain unacceptable characters, encode all of them - aParams += ";typename=\"" + lcl_getAuthorizedCharsString(rObjDesc.maTypeName) + "\""; + aParams += ";typename=\"" + rObjDesc.maTypeName + "\""; } if( !rObjDesc.maDisplayName.isEmpty() ) { // the display name might contain unacceptable characters, encode all of them - aParams += ";displayname=\"" + lcl_getAuthorizedCharsString(rObjDesc.maDisplayName) + "\""; + // this seems to be the only parameter currently that might contain such characters + sal_Bool pToAccept[128]; + for (sal_Bool & rb : pToAccept) + rb = false; + + const char aQuotedParamChars[] = + "()<>@,;:/[]?=!#$&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~. "; + + for ( sal_Int32 nInd = 0; nInd < RTL_CONSTASCII_LENGTH(aQuotedParamChars); ++nInd ) + { + sal_Unicode nChar = aQuotedParamChars[nInd]; + if ( nChar < 128 ) + pToAccept[nChar] = true; + } + + aParams += ";displayname=\"" + + rtl::Uri::encode( + rObjDesc.maDisplayName, pToAccept, rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8) + + "\""; } aParams += ";viewaspect=\"" + OUString::number(rObjDesc.mnViewAspect) @@ -188,7 +187,7 @@ static void ImplSetParameterString( TransferableObjectDescriptor& rObjDesc, cons if( xMimeType->hasParameter( aTypeNameString ) ) { - rObjDesc.maTypeName = ::rtl::Uri::decode( xMimeType->getParameterValue( aTypeNameString ), rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); + rObjDesc.maTypeName = xMimeType->getParameterValue( aTypeNameString ); } if( xMimeType->hasParameter( aDisplayNameString ) ) @@ -1202,9 +1201,8 @@ void TransferableDataHelper::FillDataFlavorExVector( const Sequence< DataFlavor if( !rFlavor.MimeType.isEmpty() ) xMimeType = xMimeFact->createMimeContentType( rFlavor.MimeType ); } - catch( const css::uno::Exception& e) + catch( const css::uno::Exception& ) { - SAL_WARN("svtools.misc", "Something went wrong with calling to createMimeContentType: \"" << e << "\""); } aFlavorEx.MimeType = rFlavor.MimeType; commit b75e3ded1f73c943fb09f117e476e367ac0c3413 Author: Stephan Bergmann <[email protected]> AuthorDate: Thu Oct 11 17:31:30 2018 +0200 Commit: Stephan Bergmann <[email protected]> CommitDate: Thu Oct 11 20:38:48 2018 +0200 tdf#120158: Base CMimeContentType on INetMIME::scanContentType ...instead of using yet another local implementation of parsing media types. CMimeContentType is the implementation of the UNO css.datatransfer.XMimeContentType interface. One observable change in behavior is that type, subtype, and parameter names will now always be reported in lower case instead of with the casing from the input preserved (but those differences in casing are functionally equivalent per the media type specification). Also, parameter names supplied to the hasParameter and getParameterValue functions are now also treated case-insensitive. The upside of this change is that INetMIME::scanContentType (via "The encoding of rMediaType should be US-ASCII, but any Unicode values in the range U+0080.. U+FFFF are interpreted 'as appropriate.'") already implicitly supports RFC 6532 "Internationalized Email Headers" extensions for media types, allowing quoted- string parameter values to contain non-ASCII Unicode characters. That means that tfd#120158 "Impossible to paste special in Writer from Calc in Libreoffice 6.1.x in some UI languages - the dialogue caption says 'unknown source'" can be fixed by just allowing non-ASCII typename parameters being generated in ImplGetParameterString in svtools/source/misc/transfer.cxx, and reverting the problematic (see the comments there) previous fix <https://gerrit.libreoffice.org/61601> "tdf#120158: fix ImplGetParameterString for typename". (Which will be done in a follow-up commit, to ease potential backporting, as that previous fix has already been backported to some versions but not to others.) Change-Id: I5d4d3586e8046f288a97605b000e262a8db5a4e9 Reviewed-on: https://gerrit.libreoffice.org/61684 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> diff --git a/dtrans/Library_mcnttype.mk b/dtrans/Library_mcnttype.mk index c139e88fed27..2442a01cb721 100644 --- a/dtrans/Library_mcnttype.mk +++ b/dtrans/Library_mcnttype.mk @@ -27,6 +27,7 @@ $(eval $(call gb_Library_use_libraries,mcnttype,\ cppu \ cppuhelper \ sal \ + tl \ )) $(eval $(call gb_Library_add_exception_objects,mcnttype,\ diff --git a/dtrans/source/cnttype/mcnttype.cxx b/dtrans/source/cnttype/mcnttype.cxx index f844c7998dd7..483806163bea 100644 --- a/dtrans/source/cnttype/mcnttype.cxx +++ b/dtrans/source/cnttype/mcnttype.cxx @@ -20,21 +20,16 @@ #include <sal/config.h> #include <com/sun/star/container/NoSuchElementException.hpp> -#include <rtl/ustrbuf.hxx> +#include <rtl/ustring.hxx> +#include <tools/inetmime.hxx> #include "mcnttype.hxx" using namespace com::sun::star::uno; -using namespace com::sun::star::lang; using namespace com::sun::star::container; using namespace std; using namespace osl; -const char TSPECIALS[] = "()<>@,;:\\\"/[]?="; -const char TOKEN[] = "!#$%&'*+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~."; -const char SPACE[] = " "; -const char SEMICOLON[] = ";"; - CMimeContentType::CMimeContentType( const OUString& aCntType ) { init( aCntType ); @@ -76,267 +71,38 @@ Sequence< OUString > SAL_CALL CMimeContentType::getParameters( ) sal_Bool SAL_CALL CMimeContentType::hasParameter( const OUString& aName ) { MutexGuard aGuard( m_aMutex ); - return ( m_ParameterMap.end( ) != m_ParameterMap.find( aName ) ); + return ( m_ParameterMap.end( ) != m_ParameterMap.find( aName.toAsciiLowerCase() ) ); } OUString SAL_CALL CMimeContentType::getParameterValue( const OUString& aName ) { + auto const lower = aName.toAsciiLowerCase(); + MutexGuard aGuard( m_aMutex ); - if ( !hasParameter( aName ) ) + if ( !hasParameter( lower ) ) throw NoSuchElementException( ); - return m_ParameterMap.find( aName )->second; + return m_ParameterMap.find( lower )->second; } void CMimeContentType::init( const OUString& aCntType ) { - if ( aCntType.isEmpty( ) ) - throw IllegalArgumentException( ); - - m_nPos = 0; - m_ContentType = aCntType; - getSym( ); - type(); -} - -void CMimeContentType::getSym() -{ - if ( m_nPos < m_ContentType.getLength( ) ) + INetContentTypeParameterList params; + if (INetMIME::scanContentType(aCntType, &m_MediaType, &m_MediaSubtype, ¶ms) + != aCntType.getStr() + aCntType.getLength()) { - m_nxtSym = m_ContentType.copy(m_nPos, 1); - ++m_nPos; - return; + throw css::lang::IllegalArgumentException( + "illegal media type " + aCntType, css::uno::Reference<css::uno::XInterface>(), -1); } - - m_nxtSym = OUString( ); -} - -void CMimeContentType::acceptSym( const OUString& pSymTlb ) -{ - if ( pSymTlb.indexOf( m_nxtSym ) < 0 ) - throw IllegalArgumentException( ); - - getSym(); -} - -void CMimeContentType::skipSpaces() -{ - while (m_nxtSym == SPACE) - getSym( ); -} - -void CMimeContentType::type() -{ - skipSpaces( ); - - OUString sToken(TOKEN); - - // check FIRST( type ) - if ( !isInRange( m_nxtSym, sToken ) ) - throw IllegalArgumentException( ); - - // parse - while( !m_nxtSym.isEmpty( ) ) - { - if ( isInRange( m_nxtSym, sToken ) ) - m_MediaType += m_nxtSym; - else if ( isInRange( m_nxtSym, "/ " ) ) - break; - else - throw IllegalArgumentException( ); - getSym( ); - } - - // check FOLLOW( type ) - skipSpaces( ); - acceptSym( "/" ); - - subtype( ); -} - -void CMimeContentType::subtype() -{ - skipSpaces( ); - - OUString sToken(TOKEN); - - // check FIRST( subtype ) - if ( !isInRange( m_nxtSym, sToken ) ) - throw IllegalArgumentException( ); - - while( !m_nxtSym.isEmpty( ) ) - { - if ( isInRange( m_nxtSym, sToken ) ) - m_MediaSubtype += m_nxtSym; - else if ( isInRange( m_nxtSym, "; " ) ) - break; - else - throw IllegalArgumentException( ); - getSym( ); - } - - // parse the rest - skipSpaces( ); - trailer(); -} - -void CMimeContentType::trailer() -{ - OUString sToken(TOKEN); - while( !m_nxtSym.isEmpty( ) ) - { - if ( m_nxtSym == "(" ) - { - getSym( ); - comment( ); - acceptSym( ")" ); + for (auto const & i: params) { + if (!i.second.m_bConverted) { + throw css::lang::IllegalArgumentException( + "illegal parameter value in media type " + aCntType, + css::uno::Reference<css::uno::XInterface>(), -1); } - else if ( m_nxtSym == ";" ) - { - // get the parameter name - getSym( ); - skipSpaces( ); - - if ( !isInRange( m_nxtSym, sToken ) ) - throw IllegalArgumentException( ); - - OUString pname = pName( ); - - skipSpaces(); - acceptSym( "=" ); - - // get the parameter value - skipSpaces( ); - - OUString pvalue = pValue( ); - - // insert into map - if ( !m_ParameterMap.insert( pair < const OUString, OUString > ( pname, pvalue ) ).second ) - throw IllegalArgumentException( ); - } - else - throw IllegalArgumentException( ); - - skipSpaces( ); + m_ParameterMap[OUString::fromUtf8(i.first)] = i.second.m_sValue; } } -OUString CMimeContentType::pName( ) -{ - OUStringBuffer pname; - - OUString sToken(TOKEN); - while( !m_nxtSym.isEmpty( ) ) - { - if ( isInRange( m_nxtSym, sToken ) ) - pname.append(m_nxtSym); - else if ( isInRange( m_nxtSym, "= " ) ) - break; - else - throw IllegalArgumentException( ); - getSym( ); - } - - return pname.makeStringAndClear(); -} - -OUString CMimeContentType::pValue( ) -{ - OUString pvalue; - - OUString sToken(TOKEN); - // quoted pvalue - if ( m_nxtSym == "\"" ) - { - getSym( ); - pvalue = quotedPValue( ); - - if ( pvalue[pvalue.getLength() - 1] != '"' ) - throw IllegalArgumentException( ); - - // remove the last quote-sign - pvalue = pvalue.copy(0, pvalue.getLength() - 1); - - if ( pvalue.isEmpty( ) ) - throw IllegalArgumentException( ); - } - else if ( isInRange( m_nxtSym, sToken ) ) // unquoted pvalue - { - pvalue = nonquotedPValue( ); - } - else - throw IllegalArgumentException( ); - - return pvalue; -} - -// the following combinations within a quoted value are not allowed: -// '";' (quote sign followed by semicolon) and '" ' (quote sign followed -// by space) - -OUString CMimeContentType::quotedPValue( ) -{ - OUStringBuffer pvalue; - bool bAfterQuoteSign = false; - - while ( !m_nxtSym.isEmpty( ) ) - { - if ( bAfterQuoteSign && ( - (m_nxtSym == SPACE) || - (m_nxtSym == SEMICOLON)) - ) - { - break; - } - else if ( isInRange( m_nxtSym, OUStringLiteral(TOKEN) + TSPECIALS + SPACE ) ) - { - pvalue.append(m_nxtSym); - bAfterQuoteSign = m_nxtSym == "\""; - } - else - throw IllegalArgumentException( ); - getSym( ); - } - - return pvalue.makeStringAndClear(); -} - -OUString CMimeContentType::nonquotedPValue( ) -{ - OUStringBuffer pvalue; - - OUString sToken(TOKEN); - while ( !m_nxtSym.isEmpty( ) ) - { - if ( isInRange( m_nxtSym, sToken ) ) - pvalue.append(m_nxtSym); - else if ( isInRange( m_nxtSym, "; " ) ) - break; - else - throw IllegalArgumentException( ); - getSym( ); - } - - return pvalue.makeStringAndClear(); -} - -void CMimeContentType::comment() -{ - while ( !m_nxtSym.isEmpty( ) ) - { - if ( isInRange( m_nxtSym, OUStringLiteral(TOKEN) + SPACE ) ) - getSym( ); - else if ( m_nxtSym == ")" ) - break; - else - throw IllegalArgumentException( ); - } -} - -bool CMimeContentType::isInRange( const OUString& aChr, const OUString& aRange ) -{ - return ( aRange.indexOf( aChr ) > -1 ); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/dtrans/source/cnttype/mcnttype.hxx b/dtrans/source/cnttype/mcnttype.hxx index 35fb37fbdba1..68c4bff5a258 100644 --- a/dtrans/source/cnttype/mcnttype.hxx +++ b/dtrans/source/cnttype/mcnttype.hxx @@ -66,10 +66,7 @@ private: ::osl::Mutex m_aMutex; OUString m_MediaType; OUString m_MediaSubtype; - OUString m_ContentType; std::map< OUString, OUString > m_ParameterMap; - sal_Int32 m_nPos; - OUString m_nxtSym; }; #endif _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
