Commit e8df7e8d authored by Max Kellermann's avatar Max Kellermann

Database*: fix nullptr dereference when no database is configured

parent af4252bc
...@@ -87,6 +87,18 @@ GetDatabase() ...@@ -87,6 +87,18 @@ GetDatabase()
return db; 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 bool
db_is_simple(void) db_is_simple(void)
{ {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define MPD_DATABASE_GLUE_HXX #define MPD_DATABASE_GLUE_HXX
#include "gcc.h" #include "gcc.h"
#include "gerror.h"
class Database; class Database;
...@@ -32,4 +33,12 @@ gcc_pure ...@@ -32,4 +33,12 @@ gcc_pure
const Database * const Database *
GetDatabase(); 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 #endif
...@@ -43,11 +43,15 @@ search_add_to_playlist(const char *uri, const char *playlist_path_utf8, ...@@ -43,11 +43,15 @@ search_add_to_playlist(const char *uri, const char *playlist_path_utf8,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const Database *db = GetDatabase(error_r);
if (db == nullptr)
return false;
const DatabaseSelection selection(uri, true, criteria); const DatabaseSelection selection(uri, true, criteria);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddSong, playlist_path_utf8, _1, _2); 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 bool
......
...@@ -115,6 +115,10 @@ bool ...@@ -115,6 +115,10 @@ bool
db_selection_print(struct client *client, const DatabaseSelection &selection, db_selection_print(struct client *client, const DatabaseSelection &selection,
bool full, GError **error_r) bool full, GError **error_r)
{ {
const Database *db = GetDatabase(error_r);
if (db == nullptr)
return false;
using namespace std::placeholders; using namespace std::placeholders;
const auto d = selection.match == nullptr const auto d = selection.match == nullptr
? std::bind(PrintDirectory, client, _1) ? std::bind(PrintDirectory, client, _1)
...@@ -126,7 +130,7 @@ db_selection_print(struct client *client, const DatabaseSelection &selection, ...@@ -126,7 +130,7 @@ db_selection_print(struct client *client, const DatabaseSelection &selection,
client, _1, _2) client, _1, _2)
: VisitPlaylist(); : VisitPlaylist();
return GetDatabase()->Visit(selection, d, s, p, error_r); return db->Visit(selection, d, s, p, error_r);
} }
struct SearchStats { struct SearchStats {
...@@ -154,6 +158,10 @@ searchStatsForSongsIn(struct client *client, const char *name, ...@@ -154,6 +158,10 @@ searchStatsForSongsIn(struct client *client, const char *name,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const Database *db = GetDatabase(error_r);
if (db == nullptr)
return false;
const DatabaseSelection selection(name, true, criteria); const DatabaseSelection selection(name, true, criteria);
SearchStats stats; SearchStats stats;
...@@ -163,7 +171,7 @@ searchStatsForSongsIn(struct client *client, const char *name, ...@@ -163,7 +171,7 @@ searchStatsForSongsIn(struct client *client, const char *name,
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(stats_visitor_song, std::ref(stats), const auto f = std::bind(stats_visitor_song, std::ref(stats),
_1); _1);
if (!GetDatabase()->Visit(selection, f, error_r)) if (!db->Visit(selection, f, error_r))
return false; return false;
printSearchStats(client, &stats); printSearchStats(client, &stats);
...@@ -206,18 +214,21 @@ listAllUniqueTags(struct client *client, int type, ...@@ -206,18 +214,21 @@ listAllUniqueTags(struct client *client, int type,
const struct locate_item_list *criteria, const struct locate_item_list *criteria,
GError **error_r) GError **error_r)
{ {
const Database *db = GetDatabase(error_r);
if (db == nullptr)
return false;
const DatabaseSelection selection("", true, criteria); const DatabaseSelection selection("", true, criteria);
if (type == LOCATE_TAG_FILE_TYPE) { if (type == LOCATE_TAG_FILE_TYPE) {
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(PrintSongURIVisitor, client, _1); const auto f = std::bind(PrintSongURIVisitor, client, _1);
return GetDatabase()->Visit(selection, f, error_r); return db->Visit(selection, f, error_r);
} else { } else {
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(PrintUniqueTag, client, const auto f = std::bind(PrintUniqueTag, client,
(enum tag_type)type, _1); (enum tag_type)type, _1);
return GetDatabase()->VisitUniqueTags(selection, return db->VisitUniqueTags(selection, (enum tag_type)type,
(enum tag_type)type, f, error_r);
f, error_r);
} }
} }
...@@ -49,11 +49,15 @@ bool ...@@ -49,11 +49,15 @@ bool
findAddIn(struct player_control *pc, const char *uri, findAddIn(struct player_control *pc, const char *uri,
const struct locate_item_list *criteria, GError **error_r) 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); const DatabaseSelection selection(uri, true, criteria);
using namespace std::placeholders; using namespace std::placeholders;
const auto f = std::bind(AddToQueue, pc, _1, _2); const auto f = std::bind(AddToQueue, pc, _1, _2);
return GetDatabase()->Visit(selection, f, error_r); return db->Visit(selection, f, error_r);
} }
bool bool
......
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