Database*: fix nullptr dereference when no database is configured
This commit is contained in:
		| @@ -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) | ||||
| { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann