From cba7f3c0ec0a4ec46c7126c5caeece203035e640 Mon Sep 17 00:00:00 2001 From: emeric Date: Thu, 17 Jul 2025 21:08:15 +0200 Subject: [PATCH] Fixed assert / infinite loop that may actually occur if artist name is too long (> 512chars), fixes #710 --- src/libs/database/impl/objects/Artist.cpp | 15 +++++++++------ .../database/impl/objects/TrackArtistLink.cpp | 7 +++++-- .../database/include/database/objects/Artist.hpp | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libs/database/impl/objects/Artist.cpp b/src/libs/database/impl/objects/Artist.cpp index 368c87ab..436f6735 100644 --- a/src/libs/database/impl/objects/Artist.cpp +++ b/src/libs/database/impl/objects/Artist.cpp @@ -35,6 +35,7 @@ #include "SqlQuery.hpp" #include "Utils.hpp" #include "traits/IdTypeTraits.hpp" +#include "traits/StringViewTraits.hpp" DBO_INSTANTIATE_TEMPLATES(lms::db::Artist) @@ -257,7 +258,10 @@ namespace lms::db { session.checkReadTransaction(); - return utils::fetchQueryResults(session.getDboSession()->query>("SELECT a FROM artist a").where("a.name = ?").bind(std::string{ name, 0, _maxNameLength }).orderBy("LENGTH(a.mbid) DESC")); // put mbid entries first + if (name.size() > maxNameLength) + name = name.substr(0, maxNameLength); + + return utils::fetchQueryResults(session.getDboSession()->query>("SELECT a FROM artist a").where("a.name = ?").bind(name).orderBy("LENGTH(a.mbid) DESC")); // put mbid entries first } Artist::pointer Artist::find(Session& session, const core::UUID& mbid) @@ -444,15 +448,14 @@ AND NOT EXISTS ( void Artist::setName(std::string_view name) { - _name.assign(name, 0, _maxNameLength); - LMS_LOG_IF(DB, WARNING, name.size() > _maxNameLength, "Artist name too long, truncated to '" << _name << "'"); + _name.assign(name, 0, maxNameLength); + LMS_LOG_IF(DB, WARNING, name.size() > maxNameLength, "Artist name too long, truncated to '" << _name << "'"); } void Artist::setSortName(std::string_view sortName) { - _sortName.assign(sortName, 0, _maxNameLength); - - LMS_LOG_IF(DB, WARNING, sortName.size() > _maxNameLength, "Artist sort name too long, truncated to '" << _sortName << "'"); + _sortName.assign(sortName, 0, maxNameLength); + LMS_LOG_IF(DB, WARNING, sortName.size() > maxNameLength, "Artist sort name too long, truncated to '" << _sortName << "'"); } void Artist::setPreferredArtwork(ObjectPtr artwork) diff --git a/src/libs/database/impl/objects/TrackArtistLink.cpp b/src/libs/database/impl/objects/TrackArtistLink.cpp index d68d606e..90a373ff 100644 --- a/src/libs/database/impl/objects/TrackArtistLink.cpp +++ b/src/libs/database/impl/objects/TrackArtistLink.cpp @@ -21,6 +21,7 @@ #include +#include "core/ILogger.hpp" #include "database/Session.hpp" #include "database/objects/Artist.hpp" #include "database/objects/Track.hpp" @@ -177,11 +178,13 @@ namespace lms::db void TrackArtistLink::setArtistName(std::string_view artistName) { - _artistName = artistName; + _artistName.assign(artistName, 0, Artist::maxNameLength); + LMS_LOG_IF(DB, WARNING, artistName.size() > Artist::maxNameLength, "Artist link name too long, truncated to '" << _artistName << "'"); } void TrackArtistLink::setArtistSortName(std::string_view artistSortName) { - _artistSortName = artistSortName; + _artistSortName.assign(artistSortName, 0, Artist::maxNameLength); + LMS_LOG_IF(DB, WARNING, artistSortName.size() > Artist::maxNameLength, "Artist link sort name too long, truncated to '" << _artistSortName << "'"); } } // namespace lms::db diff --git a/src/libs/database/include/database/objects/Artist.hpp b/src/libs/database/include/database/objects/Artist.hpp index b33e1705..6310e283 100644 --- a/src/libs/database/include/database/objects/Artist.hpp +++ b/src/libs/database/include/database/objects/Artist.hpp @@ -58,6 +58,8 @@ namespace lms::db class Artist final : public Object { public: + static constexpr std::size_t maxNameLength{ 512 }; + struct FindParameters { Filters filters; @@ -173,8 +175,6 @@ namespace lms::db } private: - static constexpr std::size_t _maxNameLength{ 512 }; - friend class Session; // Create Artist(const std::string& name, const std::optional& MBID = {});