From e8df7e8da5a075178224b130c0602b62c85508a9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 22 Aug 2012 21:40:20 +0200 Subject: Database*: fix nullptr dereference when no database is configured --- src/DatabaseGlue.cxx | 12 ++++++++++++ src/DatabaseGlue.hxx | 9 +++++++++ src/DatabasePlaylist.cxx | 6 +++++- src/DatabasePrint.cxx | 23 +++++++++++++++++------ src/DatabaseQueue.cxx | 6 +++++- 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/DatabaseGlue.cxx b/src/DatabaseGlue.cxx index 88b25d86..b980ded8 100644 --- a/src/DatabaseGlue.cxx +++ b/src/DatabaseGlue.cxx @@ -87,6 +87,18 @@ GetDatabase() return db; } +const Database * +GetDatabase(GError **error_r) +{ + assert(db == nullptr || db_is_open); + + if (db == nullptr) + g_set_error_literal(error_r, db_quark(), DB_DISABLED, + "No database"); + + return db; +} + bool db_is_simple(void) { diff --git a/src/DatabaseGlue.hxx b/src/DatabaseGlue.hxx index 79eea135..b38ba595 100644 --- a/src/DatabaseGlue.hxx +++ b/src/DatabaseGlue.hxx @@ -21,6 +21,7 @@ #define MPD_DATABASE_GLUE_HXX #include "gcc.h" +#include "gerror.h" class Database; @@ -32,4 +33,12 @@ gcc_pure const Database * GetDatabase(); +/** + * Returns the global #Database instance. May return NULL if this MPD + * configuration has no database (no music_directory was configured). + */ +gcc_pure +const Database * +GetDatabase(GError **error_r); + #endif diff --git a/src/DatabasePlaylist.cxx b/src/DatabasePlaylist.cxx index c6ad9c54..69d87dfd 100644 --- a/src/DatabasePlaylist.cxx +++ b/src/DatabasePlaylist.cxx @@ -43,11 +43,15 @@ search_add_to_playlist(const char *uri, const char *playlist_path_utf8, const struct locate_item_list *criteria, GError **error_r) { + const Database *db = GetDatabase(error_r); + if (db == nullptr) + return false; + const DatabaseSelection selection(uri, true, criteria); using namespace std::placeholders; const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2); - return GetDatabase()->Visit(selection, f, error_r); + return db->Visit(selection, f, error_r); } bool diff --git a/src/DatabasePrint.cxx b/src/DatabasePrint.cxx index b58619a9..62167972 100644 --- a/src/DatabasePrint.cxx +++ b/src/DatabasePrint.cxx @@ -115,6 +115,10 @@ bool db_selection_print(struct client *client, const DatabaseSelection &selection, bool full, GError **error_r) { + const Database *db = GetDatabase(error_r); + if (db == nullptr) + return false; + using namespace std::placeholders; const auto d = selection.match == nullptr ? std::bind(PrintDirectory, client, _1) @@ -126,7 +130,7 @@ db_selection_print(struct client *client, const DatabaseSelection &selection, client, _1, _2) : VisitPlaylist(); - return GetDatabase()->Visit(selection, d, s, p, error_r); + return db->Visit(selection, d, s, p, error_r); } struct SearchStats { @@ -154,6 +158,10 @@ searchStatsForSongsIn(struct client *client, const char *name, const struct locate_item_list *criteria, GError **error_r) { + const Database *db = GetDatabase(error_r); + if (db == nullptr) + return false; + const DatabaseSelection selection(name, true, criteria); SearchStats stats; @@ -163,7 +171,7 @@ searchStatsForSongsIn(struct client *client, const char *name, using namespace std::placeholders; const auto f = std::bind(stats_visitor_song, std::ref(stats), _1); - if (!GetDatabase()->Visit(selection, f, error_r)) + if (!db->Visit(selection, f, error_r)) return false; printSearchStats(client, &stats); @@ -206,18 +214,21 @@ listAllUniqueTags(struct client *client, int type, const struct locate_item_list *criteria, GError **error_r) { + const Database *db = GetDatabase(error_r); + if (db == nullptr) + return false; + const DatabaseSelection selection("", true, criteria); if (type == LOCATE_TAG_FILE_TYPE) { using namespace std::placeholders; const auto f = std::bind(PrintSongURIVisitor, client, _1); - return GetDatabase()->Visit(selection, f, error_r); + return db->Visit(selection, f, error_r); } else { using namespace std::placeholders; const auto f = std::bind(PrintUniqueTag, client, (enum tag_type)type, _1); - return GetDatabase()->VisitUniqueTags(selection, - (enum tag_type)type, - f, error_r); + return db->VisitUniqueTags(selection, (enum tag_type)type, + f, error_r); } } diff --git a/src/DatabaseQueue.cxx b/src/DatabaseQueue.cxx index 26ac2c6f..0e6e5784 100644 --- a/src/DatabaseQueue.cxx +++ b/src/DatabaseQueue.cxx @@ -49,11 +49,15 @@ bool findAddIn(struct player_control *pc, const char *uri, const struct locate_item_list *criteria, GError **error_r) { + const Database *db = GetDatabase(error_r); + if (db == nullptr) + return false; + const DatabaseSelection selection(uri, true, criteria); using namespace std::placeholders; const auto f = std::bind(AddToQueue, pc, _1, _2); - return GetDatabase()->Visit(selection, f, error_r); + return db->Visit(selection, f, error_r); } bool -- cgit v1.2.3