1
0
Fork 0
mirror of https://github.com/KingDuckZ/dindexer.git synced 2025-02-20 12:14:55 +00:00

Crash fix - make path on the fly

Newer versions of gcc have a small string optimizations that makes
moving FileRecordData objects behave incorrectly. When a small string is
moved, string_refs into it become invalid. Making a path on the fly
using the path() method also has the side effect of making
FileRecordData smaller in size.
This commit is contained in:
King_DuckZ 2016-05-17 20:21:44 +02:00
parent 21c5b3efcb
commit 8c03ba15bc
5 changed files with 24 additions and 21 deletions

View file

@ -39,11 +39,11 @@ namespace mchlib {
mime_full(), mime_full(),
atime(parATime), atime(parATime),
mtime(parMTime), mtime(parMTime),
path(abs_path),
mime_type(), mime_type(),
mime_charset(), mime_charset(),
size(0), size(0),
level(parLevel), level(parLevel),
path_offset(0),
is_directory(parIsDir), is_directory(parIsDir),
is_symlink(parIsSymLink), is_symlink(parIsSymLink),
unreadable(false), unreadable(false),
@ -51,22 +51,23 @@ namespace mchlib {
{ {
} }
FileRecordData ( std::string&& parPath, std::size_t parRelPathOffs, std::time_t parATime, std::time_t parMTime, uint16_t parLevel, bool parIsDir, bool parIsSymLink ) : FileRecordData ( std::string&& parPath, uint16_t parRelPathOffs, std::time_t parATime, std::time_t parMTime, uint16_t parLevel, bool parIsDir, bool parIsSymLink ) :
hash {}, hash {},
abs_path(std::move(parPath)), abs_path(std::move(parPath)),
mime_full(), mime_full(),
atime(parATime), atime(parATime),
mtime(parMTime), mtime(parMTime),
path(boost::string_ref(abs_path).substr(parRelPathOffs)),
mime_type(), mime_type(),
mime_charset(), mime_charset(),
size(0), size(0),
level(parLevel), level(parLevel),
path_offset(parRelPathOffs),
is_directory(parIsDir), is_directory(parIsDir),
is_symlink(parIsSymLink), is_symlink(parIsSymLink),
unreadable(false), unreadable(false),
hash_valid(false) hash_valid(false)
{ {
assert(path_offset <= abs_path.size());
} }
#if defined(NDEBUG) #if defined(NDEBUG)
@ -81,16 +82,18 @@ namespace mchlib {
bool operator== ( const FileRecordData& parOther ) const; bool operator== ( const FileRecordData& parOther ) const;
#endif #endif
boost::string_ref path ( void ) const { return boost::string_ref(abs_path).substr(path_offset); }
TigerHash hash; TigerHash hash;
std::string abs_path; std::string abs_path;
mime_string mime_full; mime_string mime_full;
std::time_t atime; std::time_t atime;
std::time_t mtime; std::time_t mtime;
boost::string_ref path;
boost::string_ref mime_type; boost::string_ref mime_type;
boost::string_ref mime_charset; boost::string_ref mime_charset;
uint64_t size; uint64_t size;
uint16_t level; uint16_t level;
uint16_t path_offset; //Relative path starting character into abs_path
bool is_directory; bool is_directory;
bool is_symlink; bool is_symlink;
bool unreadable; bool unreadable;

View file

@ -24,14 +24,14 @@
namespace mchlib { namespace mchlib {
namespace implem { namespace implem {
bool glob_matches (const FileRecordData& parData, const char* parGlob) { bool glob_matches (const FileRecordData& parData, const char* parGlob) {
assert(parData.path.data()); assert(parData.path().data());
//assert that the substring in path terminates at the same place //assert that the substring in path terminates at the same place
//where the one in abs_path terminates (ie: it's null-terminated). //where the one in abs_path terminates (ie: it's null-terminated).
assert(parData.path == std::string(parData.path.data())); assert(parData.path() == std::string(parData.path().data()));
//See https://github.com/FlibbleMr/neolib/blob/master/include/neolib/string_utils.hpp //See https://github.com/FlibbleMr/neolib/blob/master/include/neolib/string_utils.hpp
//for an alternative to fnmatch() (grep wildcard_match) //for an alternative to fnmatch() (grep wildcard_match)
const int match = fnmatch(parGlob, parData.path.data(), FNM_PATHNAME); const int match = fnmatch(parGlob, parData.path().data(), FNM_PATHNAME);
return not match; return not match;
} }
} //namespace implem } //namespace implem

View file

@ -69,7 +69,7 @@ namespace mchlib {
for (auto it = parList.begin(); it != parList.end(); ++it) { for (auto it = parList.begin(); it != parList.end(); ++it) {
assert(PathName(parEntry.abs_path) == PathName(it->abs_path).pop_right()); assert(PathName(parEntry.abs_path) == PathName(it->abs_path).pop_right());
PathName curr_path(it->path); PathName curr_path(it->path());
const auto basename = mchlib::basename(curr_path); const auto basename = mchlib::basename(curr_path);
if (it->is_directory) { if (it->is_directory) {
auto cd_list = MutableSetListingView(it); auto cd_list = MutableSetListingView(it);

View file

@ -99,14 +99,14 @@ namespace mchlib {
{ {
assert(parBasePath); assert(parBasePath);
assert(m_base_path or m_current == m_end); assert(m_base_path or m_current == m_end);
assert(m_current == m_end or m_base_path->atom_count() == PathName(m_current->path).atom_count() + parLevelOffset); assert(m_current == m_end or m_base_path->atom_count() == PathName(m_current->path()).atom_count() + parLevelOffset);
assert(m_current == m_end or m_base_path->atom_count() == m_current->level + m_level_offset); assert(m_current == m_end or m_base_path->atom_count() == m_current->level + m_level_offset);
//Look for the point where the children of this entry start //Look for the point where the children of this entry start
while ( while (
m_current != m_end and ( m_current != m_end and (
m_current->level + m_level_offset == m_base_path->atom_count() or m_current->level + m_level_offset == m_base_path->atom_count() or
*m_base_path != PathName(m_current->path).pop_right() *m_base_path != PathName(m_current->path()).pop_right()
)) { )) {
assert(m_base_path); assert(m_base_path);
++m_current; ++m_current;
@ -157,13 +157,13 @@ namespace mchlib {
template <bool Const> template <bool Const>
void DirIterator<Const>::increment() { void DirIterator<Const>::increment() {
assert(PathName(m_current->path).pop_right() == *m_base_path); assert(PathName(m_current->path()).pop_right() == *m_base_path);
do { do {
++m_current; ++m_current;
} while( } while(
m_current != m_end and m_current != m_end and
m_current->level + m_level_offset == m_base_path->atom_count() + 1 and m_current->level + m_level_offset == m_base_path->atom_count() + 1 and
*m_base_path != PathName(m_current->path).pop_right() *m_base_path != PathName(m_current->path()).pop_right()
); );
} }
@ -222,7 +222,7 @@ namespace mchlib {
assert(std::equal(m_list.begin(), m_list.end(), SetListing(ListType(m_list), true).sorted_list().begin())); assert(std::equal(m_list.begin(), m_list.end(), SetListing(ListType(m_list), true).sorted_list().begin()));
} }
if (not m_list.empty()) { if (not m_list.empty()) {
m_base_path.reset(new PathName(m_list.front().path)); m_base_path.reset(new PathName(m_list.front().path()));
} }
} }
@ -289,17 +289,17 @@ namespace mchlib {
} }
SetListingView<false> SetListing::make_view() { SetListingView<false> SetListing::make_view() {
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count()); const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
return SetListingView<false>(m_list.begin(), m_list.end(), offs, m_base_path); return SetListingView<false>(m_list.begin(), m_list.end(), offs, m_base_path);
} }
SetListingView<true> SetListing::make_view() const { SetListingView<true> SetListing::make_view() const {
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count()); const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path); return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path);
} }
SetListingView<true> SetListing::make_cview() const { SetListingView<true> SetListing::make_cview() const {
const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path).atom_count()); const auto offs = (m_list.empty() ? 0 : PathName(m_list.front().path()).atom_count());
return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path); return SetListingView<true>(m_list.begin(), m_list.end(), offs, m_base_path);
} }
@ -311,7 +311,7 @@ namespace mchlib {
m_level_offset(parIter.m_level_offset) m_level_offset(parIter.m_level_offset)
{ {
if (m_begin != m_end) { if (m_begin != m_end) {
m_base_path.reset(new PathName(m_begin->path)); m_base_path.reset(new PathName(m_begin->path()));
} }
} }
@ -323,7 +323,7 @@ namespace mchlib {
m_level_offset(parLevelOffset) m_level_offset(parLevelOffset)
{ {
if (m_begin != m_end) { if (m_begin != m_end) {
m_base_path.reset(new PathName(m_begin->path)); m_base_path.reset(new PathName(m_begin->path()));
} }
} }

View file

@ -60,7 +60,7 @@ namespace din {
if (parItem.abs_path.size() != 1 or parItem.abs_path != "/") { if (parItem.abs_path.size() != 1 or parItem.abs_path != "/") {
parItem.abs_path = std::string("/") + parItem.abs_path; parItem.abs_path = std::string("/") + parItem.abs_path;
} }
parItem.path = boost::string_ref(parItem.abs_path).substr(1); parItem.path_offset = 1;
} }
{ {
@ -125,9 +125,9 @@ namespace din {
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);"; "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);";
const auto& itm = parData[z]; const auto& itm = parData[z];
assert(itm.path.data()); assert(itm.path().data());
conn.query(query, conn.query(query,
(itm.path.empty() ? empty_path_string : itm.path), (itm.path().empty() ? empty_path_string : itm.path()),
tiger_to_string(itm.hash), tiger_to_string(itm.hash),
itm.level, itm.level,
new_group_id, new_group_id,