diff options
Diffstat (limited to 'filter/source/config/cache/typedetection.cxx')
-rw-r--r-- | filter/source/config/cache/typedetection.cxx | 338 |
1 files changed, 218 insertions, 120 deletions
diff --git a/filter/source/config/cache/typedetection.cxx b/filter/source/config/cache/typedetection.cxx index e9e149511cff..065fe483a3dd 100644 --- a/filter/source/config/cache/typedetection.cxx +++ b/filter/source/config/cache/typedetection.cxx @@ -25,16 +25,25 @@ #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/embed/StorageFormats.hpp> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/packages/zip/ZipIOException.hpp> #include <com/sun/star/task/XInteractionHandler.hpp> + +#include <sfx2/brokenpackageint.hxx> +#include <o3tl/string_view.hxx> #include <tools/wldcrd.hxx> #include <sal/log.hxx> #include <framework/interaction.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <tools/urlobj.hxx> #include <comphelper/fileurl.hxx> +#include <comphelper/lok.hxx> #include <comphelper/sequence.hxx> +#include <comphelper/scopeguard.hxx> +#include <utility> #define DEBUG_TYPE_DETECTION 0 @@ -53,9 +62,8 @@ TypeDetection::TypeDetection(const css::uno::Reference< css::uno::XComponentCont , m_xTerminateListener(new TerminateDetection(this)) , m_bCancel(false) { - css::frame::Desktop::create(m_xContext)->addTerminateListener(m_xTerminateListener.get()); - BaseContainer::init(rxContext , - "com.sun.star.comp.filter.config.TypeDetection" , + css::frame::Desktop::create(m_xContext)->addTerminateListener(m_xTerminateListener); + BaseContainer::init("com.sun.star.comp.filter.config.TypeDetection" , { "com.sun.star.document.TypeDetection" }, FilterCache::E_TYPE ); } @@ -63,7 +71,7 @@ TypeDetection::TypeDetection(const css::uno::Reference< css::uno::XComponentCont TypeDetection::~TypeDetection() { - css::frame::Desktop::create(m_xContext)->removeTerminateListener(m_xTerminateListener.get()); + css::frame::Desktop::create(m_xContext)->removeTerminateListener(m_xTerminateListener); } @@ -72,7 +80,7 @@ OUString SAL_CALL TypeDetection::queryTypeByURL(const OUString& sURL) OUString sType; // SAFE -> - osl::MutexGuard aLock(m_aLock); + std::unique_lock aLock(m_aMutex); css::util::URL aURL; aURL.Complete = sURL; @@ -82,7 +90,7 @@ OUString SAL_CALL TypeDetection::queryTypeByURL(const OUString& sURL) // set std types as minimum requirement first! // Only in case no type was found for given URL, // use optional types too ... - auto & cache = TheFilterCache::get(); + auto & cache = GetTheFilterCache(); FlatDetection lFlatTypes; cache.detectFlatForURL(aURL, lFlatTypes); @@ -125,7 +133,7 @@ namespace { * In each category, rank them from strictly-structured to * loosely-structured. */ -int getFlatTypeRank(const OUString& rType) +int getFlatTypeRank(std::u16string_view rType) { // List formats from more complex to less complex. // TODO: Add more. @@ -210,6 +218,7 @@ int getFlatTypeRank(const OUString& rType) "calc_SYLK", "calc_DIF", "calc_dBase", + "Apache Parquet", // Binary (raster and vector image files) "emf_MS_Windows_Metafile", @@ -232,6 +241,7 @@ int getFlatTypeRank(const OUString& rType) "pcd_Photo_CD_Base", "pcd_Photo_CD_Base4", "pcd_Photo_CD_Base16", + "webp_WebP", "impress_CGM_Computer_Graphics_Metafile", // There is binary and ascii variants ? "draw_WordPerfect_Graphics", "draw_Visio_Document", @@ -273,6 +283,7 @@ int getFlatTypeRank(const OUString& rType) // Export only "writer_layout_dump_xml", + "writer_indexing_export", "graphic_HTML", // Internal use only @@ -281,11 +292,11 @@ int getFlatTypeRank(const OUString& rType) "math_MathType_3x", // MathType equation embedded in Word doc. }; - size_t n = SAL_N_ELEMENTS(ranks); + size_t n = std::size(ranks); for (size_t i = 0; i < n; ++i) { - if (rType.equalsAscii(ranks[i])) + if (o3tl::equalsAscii(rType, ranks[i])) return n - i - 1; } @@ -343,7 +354,7 @@ class FindByType { OUString maType; public: - explicit FindByType(const OUString& rType) : maType(rType) {} + explicit FindByType(OUString aType) : maType(std::move(aType)) {} bool operator() (const FlatDetectionInfo& rInfo) const { return rInfo.sType == maType; @@ -376,10 +387,10 @@ OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css:: try { // SAFE -> ---------------------------------- - osl::ClearableMutexGuard aLock(m_aLock); + std::unique_lock aLock(m_aMutex); // parse given URL to split it into e.g. main and jump marks ... - sURL = stlDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL(), OUString()); + sURL = stlDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL, OUString()); #if OSL_DEBUG_LEVEL > 0 if (stlDescriptor.find( "FileName" ) != stlDescriptor.end()) @@ -392,19 +403,19 @@ OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css:: xParser->parseStrict(aURL); OUString aSelectedFilter = stlDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_FILTERNAME(), OUString()); + utl::MediaDescriptor::PROP_FILTERNAME, OUString()); if (!aSelectedFilter.isEmpty()) { // Caller specified the filter type. Honor it. Just get the default // type for that filter, and bail out. if (impl_validateAndSetFilterOnDescriptor(stlDescriptor, aSelectedFilter)) - return stlDescriptor[utl::MediaDescriptor::PROP_TYPENAME()].get<OUString>(); + return stlDescriptor[utl::MediaDescriptor::PROP_TYPENAME].get<OUString>(); } FlatDetection lFlatTypes; - impl_getAllFormatTypes(aURL, stlDescriptor, lFlatTypes); + impl_getAllFormatTypes(aLock, aURL, stlDescriptor, lFlatTypes); - aLock.clear(); + aLock.unlock(); // <- SAFE ---------------------------------- // Properly prioritize all candidate types. @@ -421,9 +432,8 @@ OUString SAL_CALL TypeDetection::queryTypeByDescriptor(css::uno::Sequence< css:: // outside (bAllowDeep=sal_False) or break the whole detection by // throwing an exception if creation of the might needed input // stream failed by e.g. an IO exception ... - std::vector<OUString> lUsedDetectors; if (!lFlatTypes.empty()) - sType = impl_detectTypeFlatAndDeep(stlDescriptor, lFlatTypes, bAllowDeep, lUsedDetectors, sLastChance); + sType = impl_detectTypeFlatAndDeep(stlDescriptor, lFlatTypes, bAllowDeep, sLastChance); // flat detection failed // pure deep detection failed @@ -467,18 +477,18 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes // a) // Don't overwrite a might preselected filter! OUString sFilter = rDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_FILTERNAME(), + utl::MediaDescriptor::PROP_FILTERNAME, OUString()); if (!sFilter.isEmpty()) return; - auto & cache = TheFilterCache::get(); + auto & cache = GetTheFilterCache(); // b) // check a preselected document service too. // Then we have to search a suitable filter within this module. OUString sDocumentService = rDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), + utl::MediaDescriptor::PROP_DOCUMENTSERVICE, OUString()); if (!sDocumentService.isEmpty()) { @@ -487,25 +497,25 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes OUString sRealType = sType; // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); + std::unique_lock aLock(m_aMutex); // Attention: For executing next lines of code, We must be sure that // all filters already loaded :-( // That can disturb our "load on demand feature". But we have no other chance! cache.load(FilterCache::E_CONTAINS_FILTERS); - CacheItem lIProps; - lIProps[PROPNAME_DOCUMENTSERVICE] <<= sDocumentService; - lIProps[PROPNAME_TYPE ] <<= sRealType; + css::beans::NamedValue lIProps[] { + { PROPNAME_DOCUMENTSERVICE, uno::Any(sDocumentService) }, + { PROPNAME_TYPE, uno::Any(sRealType) } }; std::vector<OUString> lFilters = cache.getMatchingItemsByProps(FilterCache::E_FILTER, lIProps); - aLock.clear(); + aLock.unlock(); // <- SAFE for (auto const& filter : lFilters) { // SAFE -> - aLock.reset(); + aLock.lock(); try { CacheItem aFilter = cache.getItem(FilterCache::E_FILTER, filter); @@ -518,14 +528,14 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes break; } catch(const css::uno::Exception&) {} - aLock.clear(); + aLock.unlock(); // <- SAFE } if (!sFilter.isEmpty()) { - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME() ] <<= sRealType; - rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME ] <<= sRealType; + rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter; sType = sRealType; return; } @@ -544,19 +554,13 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes sFilter.clear(); try { - // SAFE -> - osl::ClearableMutexGuard aLock(m_aLock); - CacheItem aType = cache.getItem(FilterCache::E_TYPE, sType); aType[PROPNAME_PREFERREDFILTER] >>= sFilter; cache.getItem(FilterCache::E_FILTER, sFilter); - aLock.clear(); - // <- SAFE - // no exception => found valid type and filter => set it on the given descriptor - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME() ] <<= sType ; - rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME ] <<= sType ; + rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter; return; } catch(const css::uno::Exception&) @@ -567,27 +571,19 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes sFilter.clear(); try { - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - // Attention: For executing next lines of code, We must be sure that // all filters already loaded :-( // That can disturb our "load on demand feature". But we have no other chance! cache.load(FilterCache::E_CONTAINS_FILTERS); - CacheItem lIProps; - lIProps[PROPNAME_TYPE] <<= sType; + css::beans::NamedValue lIProps[] { + { PROPNAME_TYPE, uno::Any(sType) } }; std::vector<OUString> lFilters = cache.getMatchingItemsByProps(FilterCache::E_FILTER, lIProps); - aLock.clear(); - // <- SAFE - for (auto const& filter : lFilters) { sFilter = filter; - // SAFE -> - aLock.reset(); try { CacheItem aFilter = cache.getItem(FilterCache::E_FILTER, sFilter); @@ -599,16 +595,14 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes } catch(const css::uno::Exception&) { continue; } - aLock.clear(); - // <- SAFE sFilter.clear(); } if (!sFilter.isEmpty()) { - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME() ] <<= sType ; - rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME ] <<= sType ; + rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter; return; } } @@ -618,6 +612,7 @@ void TypeDetection::impl_checkResultsAndAddBestFilter(utl::MediaDescriptor& rDes bool TypeDetection::impl_getPreselectionForType( + std::unique_lock<std::mutex>& /*rGuard*/, const OUString& sPreSelType, const util::URL& aParsedURL, FlatDetection& rFlatTypes, bool bDocService) { // Can be used to suppress execution of some parts of this method @@ -639,10 +634,7 @@ bool TypeDetection::impl_getPreselectionForType( CacheItem aType; try { - // SAFE -> -------------------------- - osl::MutexGuard aLock(m_aLock); - aType = TheFilterCache::get().getItem(FilterCache::E_TYPE, sType); - // <- SAFE -------------------------- + aType = GetTheFilterCache().getItem(FilterCache::E_TYPE, sType); } catch(const css::container::NoSuchElementException&) { @@ -669,8 +661,8 @@ bool TypeDetection::impl_getPreselectionForType( // otherwise we must know, if it matches to the given URL really. // especially if it matches by its extension or pattern registration. - std::vector<OUString> lExtensions(comphelper::sequenceToContainer< std::vector<OUString> >(aType[PROPNAME_EXTENSIONS].get<css::uno::Sequence<OUString> >() )); - std::vector<OUString> lURLPattern(comphelper::sequenceToContainer< std::vector<OUString> >(aType[PROPNAME_URLPATTERN].get<css::uno::Sequence<OUString> >() )); + const css::uno::Sequence<OUString> lExtensions = aType[PROPNAME_EXTENSIONS].get<css::uno::Sequence<OUString> >(); + const css::uno::Sequence<OUString> lURLPattern = aType[PROPNAME_URLPATTERN].get<css::uno::Sequence<OUString> >(); for (auto const& extension : lExtensions) { @@ -719,25 +711,22 @@ bool TypeDetection::impl_getPreselectionForType( } void TypeDetection::impl_getPreselectionForDocumentService( + std::unique_lock<std::mutex>& rGuard, const OUString& sPreSelDocumentService, const util::URL& aParsedURL, FlatDetection& rFlatTypes) { // get all filters, which match to this doc service std::vector<OUString> lFilters; try { - // SAFE -> -------------------------- - osl::MutexGuard aLock(m_aLock); - // Attention: For executing next lines of code, We must be sure that // all filters already loaded :-( // That can disturb our "load on demand feature". But we have no other chance! - auto & cache = TheFilterCache::get(); + auto & cache = GetTheFilterCache(); cache.load(FilterCache::E_CONTAINS_FILTERS); - CacheItem lIProps; - lIProps[PROPNAME_DOCUMENTSERVICE] <<= sPreSelDocumentService; + css::beans::NamedValue lIProps[] { + { PROPNAME_DOCUMENTSERVICE, css::uno::Any(sPreSelDocumentService) } }; lFilters = cache.getMatchingItemsByProps(FilterCache::E_FILTER, lIProps); - // <- SAFE -------------------------- } catch (const css::container::NoSuchElementException&) { @@ -751,21 +740,20 @@ void TypeDetection::impl_getPreselectionForDocumentService( // is an easier job than removing them .-) for (auto const& filter : lFilters) { - OUString aType = impl_getTypeFromFilter(filter); + OUString aType = impl_getTypeFromFilter(rGuard, filter); if (aType.isEmpty()) continue; - impl_getPreselectionForType(aType, aParsedURL, rFlatTypes, true); + impl_getPreselectionForType(rGuard, aType, aParsedURL, rFlatTypes, true); } } -OUString TypeDetection::impl_getTypeFromFilter(const OUString& rFilterName) +OUString TypeDetection::impl_getTypeFromFilter(std::unique_lock<std::mutex>& /*rGuard*/, const OUString& rFilterName) { CacheItem aFilter; try { - osl::MutexGuard aLock(m_aLock); - aFilter = TheFilterCache::get().getItem(FilterCache::E_FILTER, rFilterName); + aFilter = GetTheFilterCache().getItem(FilterCache::E_FILTER, rFilterName); } catch (const container::NoSuchElementException&) { @@ -778,6 +766,7 @@ OUString TypeDetection::impl_getTypeFromFilter(const OUString& rFilterName) } void TypeDetection::impl_getAllFormatTypes( + std::unique_lock<std::mutex>& rGuard, const util::URL& aParsedURL, utl::MediaDescriptor const & rDescriptor, FlatDetection& rFlatTypes) { rFlatTypes.clear(); @@ -786,8 +775,7 @@ void TypeDetection::impl_getAllFormatTypes( std::vector<OUString> aFilterNames; try { - osl::MutexGuard aLock(m_aLock); - auto & cache = TheFilterCache::get(); + auto & cache = GetTheFilterCache(); cache.load(FilterCache::E_CONTAINS_FILTERS); aFilterNames = cache.getItemNames(FilterCache::E_FILTER); } @@ -799,7 +787,7 @@ void TypeDetection::impl_getAllFormatTypes( // Retrieve the default type for each of these filters, and store them. for (auto const& filterName : aFilterNames) { - OUString aType = impl_getTypeFromFilter(filterName); + OUString aType = impl_getTypeFromFilter(rGuard, filterName); if (aType.isEmpty()) continue; @@ -812,7 +800,7 @@ void TypeDetection::impl_getAllFormatTypes( { // Get all types that match the URL alone. FlatDetection aFlatByURL; - TheFilterCache::get().detectFlatForURL(aParsedURL, aFlatByURL); + GetTheFilterCache().detectFlatForURL(aParsedURL, aFlatByURL); for (auto const& elem : aFlatByURL) { FlatDetection::iterator itPos = std::find_if(rFlatTypes.begin(), rFlatTypes.end(), FindByType(elem.sType)); @@ -840,27 +828,153 @@ void TypeDetection::impl_getAllFormatTypes( rFlatTypes.erase(last, rFlatTypes.end()); // Mark pre-selected type (if any) to have it prioritized. - OUString sSelectedType = rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME(), OUString()); + OUString sSelectedType = rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_TYPENAME, OUString()); if (!sSelectedType.isEmpty()) - impl_getPreselectionForType(sSelectedType, aParsedURL, rFlatTypes, false); + impl_getPreselectionForType(rGuard, sSelectedType, aParsedURL, rFlatTypes, false); // Mark all types preferred by the current document service, to have it prioritized. - OUString sSelectedDoc = rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE(), OUString()); + OUString sSelectedDoc = rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_DOCUMENTSERVICE, OUString()); if (!sSelectedDoc.isEmpty()) - impl_getPreselectionForDocumentService(sSelectedDoc, aParsedURL, rFlatTypes); + impl_getPreselectionForDocumentService(rGuard, sSelectedDoc, aParsedURL, rFlatTypes); +} + + +static bool isBrokenZIP(const css::uno::Reference<css::io::XInputStream>& xStream, + const css::uno::Reference<css::uno::XComponentContext>& xContext) +{ + try + { + // Only consider seekable streams starting with "PK", to avoid false detections + css::uno::Reference<css::io::XSeekable> xSeek(xStream, css::uno::UNO_QUERY_THROW); + comphelper::ScopeGuard restorePos( + [xSeek, nPos = xSeek->getPosition()] + { + try + { + xSeek->seek(nPos); + } + catch (const css::uno::Exception&) + { + } + }); + css::uno::Sequence<sal_Int8> magic(2); + xStream->readBytes(magic, 2); + if (magic.getLength() < 2 || magic[0] != 'P' || magic[1] != 'K') + return false; + } + catch (const css::uno::Exception&) + { + return false; + } + + std::vector<css::uno::Any> aArguments{ + css::uno::Any(xStream), + css::uno::Any(css::beans::NamedValue("AllowRemoveOnInsert", css::uno::Any(false))), + css::uno::Any(css::beans::NamedValue("StorageFormat", + css::uno::Any(css::embed::StorageFormats::ZIP))), + }; + try + { + // If this is a broken ZIP package, or not a ZIP, this would throw ZipIOException + xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.packages.comp.ZipPackage", comphelper::containerToSequence(aArguments), + xContext); + } + catch (const css::packages::zip::ZipIOException&) + { + // Now test if repair will succeed + aArguments.emplace_back(css::beans::NamedValue("RepairPackage", css::uno::Any(true))); + try + { + // If this is a broken ZIP package that can be repaired, this would succeed, + // and the result will be not empty + if (css::uno::Reference<css::beans::XPropertySet> xPackage{ + xContext->getServiceManager()->createInstanceWithArgumentsAndContext( + "com.sun.star.packages.comp.ZipPackage", + comphelper::containerToSequence(aArguments), xContext), + css::uno::UNO_QUERY }) + if (bool bHasElements; xPackage->getPropertyValue("HasElements") >>= bHasElements) + return bHasElements; + } + catch (const css::uno::Exception&) + { + } + } + catch (const css::uno::Exception&) + { + } + // The package is either not broken, or is not a repairable ZIP + return false; } OUString TypeDetection::impl_detectTypeFlatAndDeep( utl::MediaDescriptor& rDescriptor , const FlatDetection& lFlatTypes , bool bAllowDeep , - std::vector<OUString>& rUsedDetectors, OUString& rLastChance ) { // reset it everytimes, so the outside code can distinguish between // a set and a not set value. rLastChance.clear(); - rUsedDetectors.clear(); + + // tdf#96401: First of all, check if this is a broken ZIP package. Not doing this here would + // make some filters silently not recognize their content in broken packages, and some filters + // show a warning and mistakenly claim own content based on user choice. + if (bAllowDeep && !rDescriptor.getUnpackedValueOrDefault("RepairPackage", false) + && rDescriptor.getUnpackedValueOrDefault("RepairAllowed", true) + && rDescriptor.contains(utl::MediaDescriptor::PROP_INTERACTIONHANDLER)) + { + try + { + impl_openStream(rDescriptor); + if (auto xStream = rDescriptor.getUnpackedValueOrDefault( + utl::MediaDescriptor::PROP_INPUTSTREAM, + css::uno::Reference<css::io::XInputStream>())) + { + css::uno::Reference<css::uno::XComponentContext> xContext; + + // SAFE -> + { + std::unique_lock aLock(m_aMutex); + xContext = m_xContext; + } + // <- SAFE + + if (isBrokenZIP(xStream, xContext)) + { + if (css::uno::Reference<css::task::XInteractionHandler> xInteraction{ + rDescriptor.getValue(utl::MediaDescriptor::PROP_INTERACTIONHANDLER), + css::uno::UNO_QUERY }) + { + INetURLObject aURL(rDescriptor.getUnpackedValueOrDefault( + utl::MediaDescriptor::PROP_URL, OUString())); + OUString aDocumentTitle + = aURL.getName(INetURLObject::LAST_SEGMENT, true, + INetURLObject::DecodeMechanism::WithCharset); + + // Ask the user whether they wants to try to repair + RequestPackageReparation aRequest(aDocumentTitle); + xInteraction->handle(aRequest.GetRequest()); + + if (aRequest.isApproved()) + { + // lok: we want to overwrite file in jail, so don't use template flag + const bool bIsLOK = comphelper::LibreOfficeKit::isActive(); + rDescriptor[utl::MediaDescriptor::PROP_DOCUMENTTITLE] <<= aDocumentTitle; + rDescriptor[utl::MediaDescriptor::PROP_ASTEMPLATE] <<= !bIsLOK; + rDescriptor["RepairPackage"] <<= true; + } + else + rDescriptor["RepairAllowed"] <<= false; // Do not ask again + } + } + } + } + catch (const css::uno::Exception&) + { + // No problem + } + } // step over all possible types for this URL. // solutions: @@ -898,9 +1012,9 @@ OUString TypeDetection::impl_detectTypeFlatAndDeep( utl::MediaDescriptor& r try { // SAFE -> ---------------------------------- - osl::ClearableMutexGuard aLock(m_aLock); - CacheItem aType = TheFilterCache::get().getItem(FilterCache::E_TYPE, sFlatType); - aLock.clear(); + std::unique_lock aLock(m_aMutex); + CacheItem aType = GetTheFilterCache().getItem(FilterCache::E_TYPE, sFlatType); + aLock.unlock(); OUString sDetectService; aType[PROPNAME_DETECTSERVICE] >>= sDetectService; @@ -918,10 +1032,6 @@ OUString TypeDetection::impl_detectTypeFlatAndDeep( utl::MediaDescriptor& r continue; } - // don't forget to add every real asked deep detection service here. - // Such detectors will be ignored if may be "impl_detectTypeDeepOnly()" - // must be called later! - rUsedDetectors.push_back(sDetectService); OUString sDeepType = impl_askDetectService(sDetectService, rDescriptor); // d) @@ -942,7 +1052,7 @@ void TypeDetection::impl_seekStreamToZero(utl::MediaDescriptor const & rDescript // try to seek to 0 ... // But because XSeekable is an optional interface ... try it only .-) css::uno::Reference< css::io::XInputStream > xStream = rDescriptor.getUnpackedValueOrDefault( - utl::MediaDescriptor::PROP_INPUTSTREAM(), + utl::MediaDescriptor::PROP_INPUTSTREAM, css::uno::Reference< css::io::XInputStream >()); css::uno::Reference< css::io::XSeekable > xSeek(xStream, css::uno::UNO_QUERY); if (!xSeek.is()) @@ -980,7 +1090,7 @@ OUString TypeDetection::impl_askDetectService(const OUString& sDet // SAFE -> { - osl::MutexGuard aLock(m_aLock); + std::unique_lock aLock(m_aMutex); xContext = m_xContext; } // <- SAFE @@ -1051,18 +1161,18 @@ OUString TypeDetection::impl_askDetectService(const OUString& sDet OUString TypeDetection::impl_askUserForTypeAndFilterIfAllowed(utl::MediaDescriptor& rDescriptor) { css::uno::Reference< css::task::XInteractionHandler > xInteraction = - rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_INTERACTIONHANDLER(), + rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_INTERACTIONHANDLER, css::uno::Reference< css::task::XInteractionHandler >()); if (!xInteraction.is()) return OUString(); OUString sURL = - rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL(), + rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL, OUString()); css::uno::Reference< css::io::XInputStream > xStream = - rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_INPUTSTREAM(), + rDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_INPUTSTREAM, css::uno::Reference< css::io::XInputStream >()); // Don't disturb the user for "non existing files - means empty URLs" or @@ -1096,9 +1206,8 @@ OUString TypeDetection::impl_askUserForTypeAndFilterIfAllowed(utl::MediaDescript OUString sFilter = aRequest.getFilter(); if (!impl_validateAndSetFilterOnDescriptor(rDescriptor, sFilter)) return OUString(); - OUString sType; - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME()] >>= sType; + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME] >>= sType; return sType; } catch(const css::uno::Exception&) @@ -1111,8 +1220,8 @@ OUString TypeDetection::impl_askUserForTypeAndFilterIfAllowed(utl::MediaDescript void TypeDetection::impl_openStream(utl::MediaDescriptor& rDescriptor) { bool bSuccess = false; - OUString sURL = rDescriptor.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_URL(), OUString() ); - bool bRequestedReadOnly = rDescriptor.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_READONLY(), false ); + OUString sURL = rDescriptor.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_URL, OUString() ); + bool bRequestedReadOnly = rDescriptor.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_READONLY, false ); if ( comphelper::isFileUrl( sURL ) ) { // OOo uses own file locking mechanics in case of local file @@ -1124,7 +1233,7 @@ void TypeDetection::impl_openStream(utl::MediaDescriptor& rDescriptor) if ( !bSuccess ) throw css::uno::Exception( "Could not open stream for <" + sURL + ">", - static_cast<OWeakObject *>(this)); + getXWeak()); if ( !bRequestedReadOnly ) { @@ -1132,15 +1241,15 @@ void TypeDetection::impl_openStream(utl::MediaDescriptor& rDescriptor) // this argument should be either removed or an additional argument should be added so that application // can separate the case when the user explicitly requests readonly document. // The current solution is to remove it here. - rDescriptor.erase( utl::MediaDescriptor::PROP_READONLY() ); + rDescriptor.erase( utl::MediaDescriptor::PROP_READONLY ); } } void TypeDetection::impl_removeTypeFilterFromDescriptor(utl::MediaDescriptor& rDescriptor) { - utl::MediaDescriptor::iterator pItType = rDescriptor.find(utl::MediaDescriptor::PROP_TYPENAME() ); - utl::MediaDescriptor::iterator pItFilter = rDescriptor.find(utl::MediaDescriptor::PROP_FILTERNAME()); + utl::MediaDescriptor::iterator pItType = rDescriptor.find(utl::MediaDescriptor::PROP_TYPENAME ); + utl::MediaDescriptor::iterator pItFilter = rDescriptor.find(utl::MediaDescriptor::PROP_FILTERNAME); if (pItType != rDescriptor.end()) rDescriptor.erase(pItType); if (pItFilter != rDescriptor.end()) @@ -1151,16 +1260,11 @@ void TypeDetection::impl_removeTypeFilterFromDescriptor(utl::MediaDescriptor& rD bool TypeDetection::impl_validateAndSetTypeOnDescriptor( utl::MediaDescriptor& rDescriptor, const OUString& sType ) { - // SAFE -> + if (GetTheFilterCache().hasItem(FilterCache::E_TYPE, sType)) { - osl::MutexGuard aLock(m_aLock); - if (TheFilterCache::get().hasItem(FilterCache::E_TYPE, sType)) - { - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME()] <<= sType; - return true; - } + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME] <<= sType; + return true; } - // <- SAFE // remove all related information from the descriptor impl_removeTypeFilterFromDescriptor(rDescriptor); @@ -1168,25 +1272,19 @@ bool TypeDetection::impl_validateAndSetTypeOnDescriptor( utl::MediaDescript } -bool TypeDetection::impl_validateAndSetFilterOnDescriptor( utl::MediaDescriptor& rDescriptor, - const OUString& sFilter ) +bool TypeDetection::impl_validateAndSetFilterOnDescriptor( utl::MediaDescriptor& rDescriptor, + const OUString& sFilter ) { try { - // SAFE -> - osl::ClearableMutexGuard aLock(m_aLock); - - auto & cache = TheFilterCache::get(); + auto & cache = GetTheFilterCache(); CacheItem aFilter = cache.getItem(FilterCache::E_FILTER, sFilter); OUString sType; aFilter[PROPNAME_TYPE] >>= sType; - aLock.clear(); - // <- SAFE - // found valid type and filter => set it on the given descriptor - rDescriptor[utl::MediaDescriptor::PROP_TYPENAME() ] <<= sType ; - rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter; + rDescriptor[utl::MediaDescriptor::PROP_TYPENAME ] <<= sType ; + rDescriptor[utl::MediaDescriptor::PROP_FILTERNAME] <<= sFilter; return true; } catch(const css::container::NoSuchElementException&){} |