Avoid leaking single shared file path in search results

Single shared files are a bit special and contain the full path in the
  name because they are not shared as part of a directory, epurate the
  path component from matching process and from search result
This commit is contained in:
Gioacchino Mazzurco 2021-07-18 20:14:26 +02:00
parent e1580868dc
commit 9970f9d22f
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
2 changed files with 80 additions and 43 deletions

View File

@ -3,7 +3,9 @@
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
* * * *
* Copyright 2016 by Mr.Alice <mralice@users.sourceforge.net> * * Copyright (C) 2016 Mr.Alice <mralice@users.sourceforge.net> *
* Copyright (C) 2021 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2021 Asociación Civil Altermundi <info@altermundi.net> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -29,6 +31,7 @@
#include "dir_hierarchy.h" #include "dir_hierarchy.h"
#include "filelist_io.h" #include "filelist_io.h"
#include "file_sharing_defaults.h" #include "file_sharing_defaults.h"
#include "util/cxx17retrocompat.h"
#ifdef RS_DEEP_FILES_INDEX #ifdef RS_DEEP_FILES_INDEX
# include "deep_search/filesindex.hpp" # include "deep_search/filesindex.hpp"
@ -784,27 +787,43 @@ int InternalFileHierarchyStorage::searchTerms(
const std::list<std::string>& terms, const std::list<std::string>& terms,
std::list<DirectoryStorage::EntryIndex>& results ) const std::list<DirectoryStorage::EntryIndex>& results ) const
{ {
// most entries are likely to be files, so we could do a linear search over the entries tab. /* most entries are likely to be files, so we could do a linear search over
// instead we go through the table of hashes. * the entries tab. Instead we go through the table of hashes.*/
for(std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it(mFileHashes.begin());it!=mFileHashes.end();++it) for(auto& it : std::as_const(mFileHashes))
if(mNodes[it->second] != NULL) {
{ // node may be null for some hash waiting to be deleted
const std::string &str1 = static_cast<FileEntry*>(mNodes[it->second])->file_name; if(mNodes[it.second])
{
rs_view_ptr<FileEntry> tFileEntry =
static_cast<FileEntry*>(mNodes[it.second]);
for(std::list<std::string>::const_iterator iter(terms.begin()); iter != terms.end(); ++iter) /* Most file will just have file name stored, but single file shared
{ * without a shared dir will contain full path instead of just the
/* always ignore case */ * name, so purify it to perform the search */
const std::string &str2 = (*iter); std::string tFilename = tFileEntry->file_name;
if(tFileEntry->file_name.find("/") != std::string::npos)
{
std::string _tParentDir;
RsDirUtil::splitDirFromFile(
tFileEntry->file_name, _tParentDir, tFilename );
}
if(str1.end() != std::search( str1.begin(), str1.end(), str2.begin(), str2.end(), RsRegularExpression::CompareCharIC() )) for(auto& termIt : std::as_const(terms))
{ {
results.push_back(it->second); /* always ignore case */
break; if(tFilename.end() != std::search(
} tFilename.begin(), tFilename.end(),
} termIt.begin(), termIt.end(),
} RsRegularExpression::CompareCharIC() ))
return 0 ; {
results.push_back(it.second);
break;
}
}
}
}
return 0;
} }
bool InternalFileHierarchyStorage::check(std::string& error_string) // checks consistency of storage. bool InternalFileHierarchyStorage::check(std::string& error_string) // checks consistency of storage.

View File

@ -30,7 +30,7 @@
#include "retroshare/rsids.h" #include "retroshare/rsids.h"
#include "retroshare/rspeers.h" #include "retroshare/rspeers.h"
#include "retroshare/rsinit.h" #include "retroshare/rsinit.h"
#include "util/cxx17retrocompat.h"
#include "rsserver/p3face.h" #include "rsserver/p3face.h"
#define P3FILELISTS_DEBUG() std::cerr << time(NULL) << " : FILE_LISTS : " << __FUNCTION__ << " : " #define P3FILELISTS_DEBUG() std::cerr << time(NULL) << " : FILE_LISTS : " << __FUNCTION__ << " : "
@ -1476,7 +1476,9 @@ bool p3FileDatabase::search(
return false; return false;
} }
int p3FileDatabase::filterResults(const std::list<void*>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const int p3FileDatabase::filterResults(
const std::list<void*>& firesults, std::list<DirDetails>& results,
FileSearchFlags flags, const RsPeerId& peer_id ) const
{ {
results.clear(); results.clear();
@ -1484,29 +1486,33 @@ int p3FileDatabase::filterResults(const std::list<void*>& firesults,std::list<Di
/* translate/filter results */ /* translate/filter results */
for(std::list<void*>::const_iterator rit(firesults.begin()); rit != firesults.end(); ++rit) for(void* rit: std::as_const(firesults))
{ {
DirDetails cdetails ; DirDetails cdetails;
if(!RequestDirDetails (*rit,cdetails,RS_FILE_HINTS_LOCAL)) if(!RequestDirDetails(rit, cdetails, RS_FILE_HINTS_LOCAL))
{ {
P3FILELISTS_ERROR() << "(EE) Cannot get dir details for entry " << *rit << std::endl; RS_ERR("Cannot retrieve dir details for entry: ", rit);
continue ; print_stacktrace();
} continue ;
}
RS_DBG( "Filtering candidate: ", rit,
", name: ", cdetails.name, ", path: ", cdetails.path,
", flags: ", cdetails.flags, ", peer: ", peer_id );
if(!peer_id.isNull())
{
FileSearchFlags permission_flags =
rsPeers->computePeerPermissionFlags(
peer_id, cdetails.flags, cdetails.parent_groups );
if (cdetails.type == DIR_TYPE_FILE && ( permission_flags & flags ))
{
cdetails.id.clear();
results.push_back(cdetails);
#ifdef DEBUG_P3FILELISTS #ifdef DEBUG_P3FILELISTS
P3FILELISTS_DEBUG() << "Filtering candidate " << *rit << ", flags=" << cdetails.flags << ", peer=" << peer_id ; std::cerr << ": kept" << std::endl ;
#endif
if(!peer_id.isNull())
{
FileSearchFlags permission_flags = rsPeers->computePeerPermissionFlags(peer_id,cdetails.flags,cdetails.parent_groups) ;
if (cdetails.type == DIR_TYPE_FILE && ( permission_flags & flags ))
{
cdetails.id.clear() ;
results.push_back(cdetails);
#ifdef DEBUG_P3FILELISTS
std::cerr << ": kept" << std::endl ;
#endif #endif
} }
#ifdef DEBUG_P3FILELISTS #ifdef DEBUG_P3FILELISTS
@ -1518,7 +1524,19 @@ int p3FileDatabase::filterResults(const std::list<void*>& firesults,std::list<Di
results.push_back(cdetails); results.push_back(cdetails);
} }
return !results.empty() ; for(auto& res: results)
{
/* Most file will just have file name stored, but single file shared
* without a shared dir will contain full path instead of just the
* name, so purify it to perform the search */
if(res.name.find("/") != std::string::npos )
{
std::string _tDirPath;
RsDirUtil::splitDirFromFile(res.name, _tDirPath, res.name);
}
}
return !results.empty();
} }
bool p3FileDatabase::convertSharedFilePath(const std::string& path,std::string& fullpath) bool p3FileDatabase::convertSharedFilePath(const std::string& path,std::string& fullpath)