summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b3ccd59)
raw | patch | inline | side by side (parent: b3ccd59)
author | Max Kellermann <max@duempel.org> | |
Sun, 13 Sep 2009 10:07:54 +0000 (12:07 +0200) | ||
committer | Max Kellermann <max@duempel.org> | |
Sun, 13 Sep 2009 10:07:54 +0000 (12:07 +0200) |
This also adds several "connection==NULL" checks, and thus fixes a
NULL pointer dereference, which could occur when you pressed "tab" too
early, before the connection was established (Debian bug #540415).
NULL pointer dereference, which could occur when you pressed "tab" too
early, before the connection was established (Debian bug #540415).
NEWS | patch | blob | history | |
src/mpdclient.c | patch | blob | history |
index de9f1a3aa663fb6dcb3d4c2560380d871de9ba8c..a0f14f8c2de0014141ee140fad87bc835bdb1183 100644 (file)
--- a/NEWS
+++ b/NEWS
* display song duration in the playlist
* added the "hardware_cursor" option
* show plugin error messages on the screen
+* fixed NULL pointer dereference when not yet connected
* new translation: Hebrew
diff --git a/src/mpdclient.c b/src/mpdclient.c
index eaef01f65399208d360c208535fa6fb2fc3d5bcd..0897e8607471bba86dbee1bf26dced9e7527b5f2 100644 (file)
--- a/src/mpdclient.c
+++ b/src/mpdclient.c
static bool
MPD_ERROR(const struct mpdclient *client)
{
- return client == NULL || client->connection==NULL ||
- client->connection->error != MPD_ERROR_SUCCESS;
+ return client->connection == NULL;
}
/* filelist sorting functions */
mpdclient_handle_error(mpdclient_t *c)
{
enum mpd_error error = c->connection->error;
+ bool is_fatal = error != MPD_ERROR_ACK;
if (error == MPD_ERROR_SUCCESS)
return 0;
error = error | (c->connection->errorCode << 8);
error_cb(c, error, c->connection->errorStr);
+
+ if (is_fatal)
+ mpdclient_disconnect(c);
+
return error;
}
/* connect to MPD */
c->connection = mpd_newConnection(host, port, _timeout);
- if( c->connection->error )
- return error_cb(c, c->connection->error,
- c->connection->errorStr);
+ if (c->connection->error) {
+ retval = error_cb(c, c->connection->error,
+ c->connection->errorStr);
+ if (retval != 0) {
+ mpd_closeConnection(c->connection);
+ c->connection = NULL;
+ }
+
+ return retval;
+ }
/* send password */
if( password ) {
#ifdef ENABLE_SONG_ID
struct mpd_song *song = playlist_get_song(c, idx);
+ if (MPD_ERROR(c))
+ return -1;
+
if (song)
mpd_sendPlayIdCommand(c->connection, song->id);
else
mpd_sendPlayIdCommand(c->connection, MPD_PLAY_AT_BEGINNING);
#else
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendPlayCommand(c->connection, idx);
#endif
c->need_update = TRUE;
gint
mpdclient_cmd_pause(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendPauseCommand(c->connection, value);
return mpdclient_finish_command(c);
}
bool playing;
int length, current;
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendStatusCommand(c->connection);
status = mpd_getStatus(c->connection);
error = mpdclient_finish_command(c);
gint
mpdclient_cmd_stop(mpdclient_t *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendStopCommand(c->connection);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_next(mpdclient_t *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendNextCommand(c->connection);
c->need_update = TRUE;
return mpdclient_finish_command(c);
gint
mpdclient_cmd_prev(mpdclient_t *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendPrevCommand(c->connection);
c->need_update = TRUE;
return mpdclient_finish_command(c);
gint
mpdclient_cmd_seek(mpdclient_t *c, gint id, gint pos)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendSeekIdCommand(c->connection, id, pos);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_shuffle(mpdclient_t *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendShuffleCommand(c->connection);
c->need_update = TRUE;
return mpdclient_finish_command(c);
{
gint retval = 0;
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendClearCommand(c->connection);
retval = mpdclient_finish_command(c);
/* call playlist updated callback */
gint
mpdclient_cmd_repeat(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendRepeatCommand(c->connection, value);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_random(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendRandomCommand(c->connection, value);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_single(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendSingleCommand(c->connection, value);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_consume(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendConsumeCommand(c->connection, value);
return mpdclient_finish_command(c);
}
gint
mpdclient_cmd_crossfade(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendCrossfadeCommand(c->connection, value);
return mpdclient_finish_command(c);
}
{
gint ret;
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendUpdateCommand(c->connection, path ? path : "");
ret = mpdclient_finish_command(c);
gint
mpdclient_cmd_volume(mpdclient_t *c, gint value)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendSetvolCommand(c->connection, value);
return mpdclient_finish_command(c);
}
gint mpdclient_cmd_volume_up(struct mpdclient *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME)
return 0;
gint mpdclient_cmd_volume_down(struct mpdclient *c)
{
+ if (MPD_ERROR(c))
+ return -1;
+
if (c->status == NULL || c->status->volume == MPD_STATUS_NO_VOLUME)
return 0;
gint
mpdclient_cmd_add_path(mpdclient_t *c, const gchar *path_utf8)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendAddCommand(c->connection, path_utf8);
return mpdclient_finish_command(c);
}
{
gint retval = 0;
+ if (MPD_ERROR(c))
+ return -1;
+
if( !song || !song->file )
return -1;
gint retval = 0;
struct mpd_song *song;
+ if (MPD_ERROR(c))
+ return -1;
+
if (idx < 0 || (guint)idx >= playlist_length(&c->playlist))
return -1;
gint n;
struct mpd_song *song1, *song2;
+ if (MPD_ERROR(c))
+ return -1;
+
if (old_index == new_index || new_index < 0 ||
(guint)new_index >= c->playlist.list->len)
return -1;
{
gint retval = 0;
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendSaveCommand(c->connection, filename_utf8);
if ((retval = mpdclient_finish_command(c)) == 0)
mpdclient_browse_callback(c, BROWSE_PLAYLIST_SAVED, NULL);
gint
mpdclient_cmd_load_playlist(mpdclient_t *c, const gchar *filename_utf8)
{
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendLoadCommand(c->connection, filename_utf8);
c->need_update = TRUE;
return mpdclient_finish_command(c);
{
gint retval = 0;
+ if (MPD_ERROR(c))
+ return -1;
+
mpd_sendRmCommand(c->connection, filename_utf8);
if ((retval = mpdclient_finish_command(c)) == 0)
mpdclient_browse_callback(c, BROWSE_PLAYLIST_DELETED, NULL);
mpdclient_filelist_t *filelist;
mpd_InfoEntity *entity;
+ if (MPD_ERROR(c))
+ return NULL;
+
mpd_sendLsInfoCommand(c->connection, path);
filelist = filelist_new();
if (path && path[0] && strcmp(path, "/"))
mpdclient_filelist_t *filelist;
mpd_InfoEntity *entity;
+ if (MPD_ERROR(c))
+ return NULL;
+
if (exact_match)
mpd_sendFindCommand(c->connection, table, filter_utf8);
else
{
guint i;
+ if (MPD_ERROR(c))
+ return -1;
+
if (filelist_is_empty(fl))
return 0;
gchar *str = NULL;
GList *list = NULL;
+ if (MPD_ERROR(c))
+ return NULL;
+
mpd_sendListCommand(c->connection, MPD_TABLE_ARTIST, NULL);
while ((str = mpd_getNextArtist(c->connection)))
list = g_list_append(list, (gpointer) str);
gchar *str = NULL;
GList *list = NULL;
+ if (MPD_ERROR(c))
+ return NULL;
+
mpd_sendListCommand(c->connection, MPD_TABLE_ALBUM, artist_utf8);
while ((str = mpd_getNextAlbum(c->connection)))
list = g_list_append(list, (gpointer) str);