summaryrefslogtreecommitdiff
path: root/filter/source/config/cache/typedetection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/config/cache/typedetection.cxx')
-rw-r--r--filter/source/config/cache/typedetection.cxx338
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&){}