Kaydet (Commit) f0110f79 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

file UCP: Dir entries can disappear during non-atomic traversal

...so allow for that by reporting failure to call
osl::DirectoryItem::getFileStatus from TaskManager::getv, and make
XResultSet_impl::OneMore ignore such lost entries.  While there may be
legitimate cases where getFileStatus in getv would fail (and thus SAL_INFO would
be more appropriate), the broken, non-atomic design means that such failure is
likely unexpected (and worth a SAL_WARN).

Occasionally ran into this when building UBSan builds, which sometimes failed in
one of the extras/Gallery_*.mk like

> ucb/source/ucp/file/filrset.cxx:235:60: runtime error: load of value 96, which is not a valid value for type 'bool'
>     #0 0x7f079bff575e in fileaccess::XResultSet_impl::OneMore() ucb/source/ucp/file/filrset.cxx:234:60
>     #1 0x7f079bff823e in fileaccess::XResultSet_impl::next() ucb/source/ucp/file/filrset.cxx:288:16
>     #2 0x7f0800a109a8 in Gallery::ImplLoadSubDirs(INetURLObject const&, bool&) svx/source/gallery2/gallery1.cxx:291:36
>     #3 0x7f0800a0c88c in Gallery::ImplLoad(rtl::OUString const&) svx/source/gallery2/gallery1.cxx:202:5
>     #4 0x7f0800a0bfa5 in Gallery::Gallery(rtl::OUString const&) svx/source/gallery2/gallery1.cxx:167:5
>     #5 0x522e13 in createGallery(rtl::OUString const&) svx/source/gengal/gengal.cxx:62:16
>     #6 0x52979a in createTheme(rtl::OUString const&, rtl::OUString const&, rtl::OUString const&, std::__debug::vector<INetURLObject, std::allocator<INetURLObject> >&, bool) svx/source/gengal/gengal.cxx:76:16
>     #7 0x52853d in GalApp::Main() svx/source/gengal/gengal.cxx:318:9
>     #8 0x7f080f6f8c36 in ImplSVMain() vcl/source/app/svmain.cxx:191:35
>     #9 0x7f080f706571 in SVMain() vcl/source/app/svmain.cxx:229:16
>     #10 0x56aa0a in sal_main() vcl/source/salmain/salmain.cxx:41:12
>     #11 0x56a99f in main vcl/source/salmain/salmain.cxx:35:1
>     #12 0x7f07fbaf5400 in __libc_start_main /usr/src/debug/glibc-2.24-33-ge9e69e4/csu/../csu/libc-start.c:289
>     #13 0x42e219 in _start (instdir/program/gengal.bin+0x42e219)
>
> SUMMARY: AddressSanitizer: undefined-behavior ucb/source/ucp/file/filrset.cxx:235:60 in
> solenv/gbuild/Gallery.mk:58: recipe for target 'workdir/Gallery/education.done' failed

presumably because some other part of the build changed instdir/share/config/
in parallel.  (And doing

> while (touch instdir/share/config/TEST && rm instdir/share/config/TEST); do :; done

in parallel to 'make extras' indeed causes this issue to occur easily.)

Change-Id: I115ac727f99eed209b223d828c33060b275daaaa
üst 88d3d27d
......@@ -228,8 +228,14 @@ XResultSet_impl::OneMore()
}
else if( err == osl::FileBase::E_None )
{
aRow = m_pMyShell->getv(
this, m_sProperty, aDirIte, aUnqPath, IsRegular );
if (!m_pMyShell->getv(
this, m_sProperty, aDirIte, aUnqPath, IsRegular, aRow ))
{
SAL_WARN(
"ucb.ucp.file",
"getting dir item in <" << m_aBaseDirectory << "> failed");
continue;
}
if( m_nOpenMode == ucb::OpenMode::DOCUMENTS && IsRegular )
{
......
......@@ -2528,13 +2528,14 @@ TaskManager::commit( const TaskManager::ContentMap::iterator& it,
// directoryitem, which is returned by osl::DirectoryItem::getNextItem()
uno::Reference< sdbc::XRow > SAL_CALL
bool SAL_CALL
TaskManager::getv(
Notifier* pNotifier,
const uno::Sequence< beans::Property >& properties,
osl::DirectoryItem& aDirItem,
OUString& aUnqPath,
bool& aIsRegular )
bool& aIsRegular,
uno::Reference< sdbc::XRow > & row )
{
uno::Sequence< uno::Any > seq( properties.getLength() );
......@@ -2548,57 +2549,64 @@ TaskManager::getv(
osl_FileStatus_Mask_LinkTargetURL );
osl::FileBase::RC aRes = aDirItem.getFileStatus( aFileStatus );
if ( aRes == osl::FileBase::E_None )
if ( aRes != osl::FileBase::E_None )
{
aUnqPath = aFileStatus.getFileURL();
SAL_WARN(
"ucb.ucp.file",
"osl::DirectoryItem::getFileStatus failed with " << +aRes);
return false;
}
aUnqPath = aFileStatus.getFileURL();
// If the directory item type is a link retrieve the type of the target
// If the directory item type is a link retrieve the type of the target
if ( aFileStatus.getFileType() == osl::FileStatus::Link )
if ( aFileStatus.getFileType() == osl::FileStatus::Link )
{
// Assume failure
aIsRegular = false;
osl::FileBase::RC result = osl::FileBase::E_INVAL;
osl::DirectoryItem aTargetItem;
osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
if ( aTargetItem.is() )
{
// Assume failure
aIsRegular = false;
osl::FileBase::RC result = osl::FileBase::E_INVAL;
osl::DirectoryItem aTargetItem;
osl::DirectoryItem::get( aFileStatus.getLinkTargetURL(), aTargetItem );
if ( aTargetItem.is() )
{
osl::FileStatus aTargetStatus( osl_FileStatus_Mask_Type );
osl::FileStatus aTargetStatus( osl_FileStatus_Mask_Type );
if ( osl::FileBase::E_None ==
( result = aTargetItem.getFileStatus( aTargetStatus ) ) )
aIsRegular =
aTargetStatus.getFileType() == osl::FileStatus::Regular;
}
if ( osl::FileBase::E_None ==
( result = aTargetItem.getFileStatus( aTargetStatus ) ) )
aIsRegular =
aTargetStatus.getFileType() == osl::FileStatus::Regular;
}
else
aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
}
else
aIsRegular = aFileStatus.getFileType() == osl::FileStatus::Regular;
registerNotifier( aUnqPath,pNotifier );
insertDefaultProperties( aUnqPath );
{
osl::MutexGuard aGuard( m_aMutex );
registerNotifier( aUnqPath,pNotifier );
insertDefaultProperties( aUnqPath );
{
osl::MutexGuard aGuard( m_aMutex );
TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
commit( it,aFileStatus );
TaskManager::ContentMap::iterator it = m_aContent.find( aUnqPath );
commit( it,aFileStatus );
TaskManager::PropertySet::iterator it1;
PropertySet& propset = *(it->second.properties);
TaskManager::PropertySet::iterator it1;
PropertySet& propset = *(it->second.properties);
for( sal_Int32 i = 0; i < seq.getLength(); ++i )
{
MyProperty readProp( properties[i].Name );
it1 = propset.find( readProp );
if( it1 == propset.end() )
seq[i] = uno::Any();
else
seq[i] = it1->getValue();
}
for( sal_Int32 i = 0; i < seq.getLength(); ++i )
{
MyProperty readProp( properties[i].Name );
it1 = propset.find( readProp );
if( it1 == propset.end() )
seq[i] = uno::Any();
else
seq[i] = it1->getValue();
}
deregisterNotifier( aUnqPath,pNotifier );
}
deregisterNotifier( aUnqPath,pNotifier );
XRow_impl* p = new XRow_impl( this,seq );
return uno::Reference< sdbc::XRow >( p );
row = uno::Reference< sdbc::XRow >( p );
return true;
}
......
......@@ -585,12 +585,13 @@ namespace fileaccess
// Special optimized method for getting the properties of a directoryitem, which
// is returned by osl::DirectoryItem::getNextItem()
css::uno::Reference< css::sdbc::XRow > SAL_CALL
bool SAL_CALL
getv( Notifier* pNotifier,
const css::uno::Sequence< css::beans::Property >& properties,
osl::DirectoryItem& DirItem,
OUString& aUnqPath,
bool& bIsRegular );
bool& bIsRegular,
css::uno::Reference< css::sdbc::XRow > & row );
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment