Commit caf93d9a authored by Max Kellermann's avatar Max Kellermann

playlist_list: playlist_list_open_path() returns input_stream

Memory leak fix. The input_stream object passed to playlist_list_open_stream_suffix() must be closed by the caller - this however never happens in playlist_list_open_path(), because it does not return it to the caller.
parent 747e945d
...@@ -284,7 +284,7 @@ playlist_suffix_supported(const char *suffix) ...@@ -284,7 +284,7 @@ playlist_suffix_supported(const char *suffix)
} }
struct playlist_provider * struct playlist_provider *
playlist_list_open_path(const char *path_fs) playlist_list_open_path(const char *path_fs, struct input_stream **is_r)
{ {
GError *error = NULL; GError *error = NULL;
const char *suffix; const char *suffix;
...@@ -318,7 +318,9 @@ playlist_list_open_path(const char *path_fs) ...@@ -318,7 +318,9 @@ playlist_list_open_path(const char *path_fs)
} }
playlist = playlist_list_open_stream_suffix(is, suffix); playlist = playlist_list_open_stream_suffix(is, suffix);
if (playlist == NULL) if (playlist != NULL)
*is_r = is;
else
input_stream_close(is); input_stream_close(is);
return playlist; return playlist;
......
...@@ -55,9 +55,11 @@ playlist_list_open_stream(struct input_stream *is, const char *uri); ...@@ -55,9 +55,11 @@ playlist_list_open_stream(struct input_stream *is, const char *uri);
* Opens a playlist from a local file. * Opens a playlist from a local file.
* *
* @param path_fs the path of the playlist file * @param path_fs the path of the playlist file
* @param is_r on success, an input_stream object is returned here,
* which must be closed after the playlist_provider object is freed
* @return a playlist, or NULL on error * @return a playlist, or NULL on error
*/ */
struct playlist_provider * struct playlist_provider *
playlist_list_open_path(const char *path_fs); playlist_list_open_path(const char *path_fs, struct input_stream **is_r);
#endif #endif
...@@ -27,13 +27,15 @@ ...@@ -27,13 +27,15 @@
#include <assert.h> #include <assert.h>
static struct playlist_provider * static struct playlist_provider *
playlist_open_path(const char *path_fs) playlist_open_path(const char *path_fs, struct input_stream **is_r)
{ {
struct playlist_provider *playlist; struct playlist_provider *playlist;
playlist = playlist_list_open_uri(path_fs); playlist = playlist_list_open_uri(path_fs);
if (playlist == NULL) if (playlist != NULL)
playlist = playlist_list_open_path(path_fs); *is_r = NULL;
else
playlist = playlist_list_open_path(path_fs, is_r);
return playlist; return playlist;
} }
...@@ -42,7 +44,7 @@ playlist_open_path(const char *path_fs) ...@@ -42,7 +44,7 @@ playlist_open_path(const char *path_fs)
* Load a playlist from the configured playlist directory. * Load a playlist from the configured playlist directory.
*/ */
static struct playlist_provider * static struct playlist_provider *
playlist_open_in_playlist_dir(const char *uri) playlist_open_in_playlist_dir(const char *uri, struct input_stream **is_r)
{ {
char *path_fs; char *path_fs;
...@@ -54,7 +56,7 @@ playlist_open_in_playlist_dir(const char *uri) ...@@ -54,7 +56,7 @@ playlist_open_in_playlist_dir(const char *uri)
path_fs = g_build_filename(playlist_directory_fs, uri, NULL); path_fs = g_build_filename(playlist_directory_fs, uri, NULL);
struct playlist_provider *playlist = playlist_open_path(path_fs); struct playlist_provider *playlist = playlist_open_path(path_fs, is_r);
g_free(path_fs); g_free(path_fs);
return playlist; return playlist;
...@@ -64,7 +66,7 @@ playlist_open_in_playlist_dir(const char *uri) ...@@ -64,7 +66,7 @@ playlist_open_in_playlist_dir(const char *uri)
* Load a playlist from the configured music directory. * Load a playlist from the configured music directory.
*/ */
static struct playlist_provider * static struct playlist_provider *
playlist_open_in_music_dir(const char *uri) playlist_open_in_music_dir(const char *uri, struct input_stream **is_r)
{ {
char *path_fs; char *path_fs;
...@@ -74,25 +76,25 @@ playlist_open_in_music_dir(const char *uri) ...@@ -74,25 +76,25 @@ playlist_open_in_music_dir(const char *uri)
if (path_fs == NULL) if (path_fs == NULL)
return NULL; return NULL;
struct playlist_provider *playlist = playlist_open_path(path_fs); struct playlist_provider *playlist = playlist_open_path(path_fs, is_r);
g_free(path_fs); g_free(path_fs);
return playlist; return playlist;
} }
struct playlist_provider * struct playlist_provider *
playlist_mapper_open(const char *uri) playlist_mapper_open(const char *uri, struct input_stream **is_r)
{ {
struct playlist_provider *playlist; struct playlist_provider *playlist;
if (spl_valid_name(uri)) { if (spl_valid_name(uri)) {
playlist = playlist_open_in_playlist_dir(uri); playlist = playlist_open_in_playlist_dir(uri, is_r);
if (playlist != NULL) if (playlist != NULL)
return playlist; return playlist;
} }
if (uri_safe_local(uri)) { if (uri_safe_local(uri)) {
playlist = playlist_open_in_music_dir(uri); playlist = playlist_open_in_music_dir(uri, is_r);
if (playlist != NULL) if (playlist != NULL)
return playlist; return playlist;
} }
......
...@@ -20,11 +20,17 @@ ...@@ -20,11 +20,17 @@
#ifndef MPD_PLAYLIST_MAPPER_H #ifndef MPD_PLAYLIST_MAPPER_H
#define MPD_PLAYLIST_MAPPER_H #define MPD_PLAYLIST_MAPPER_H
struct input_stream;
/** /**
* Opens a playlist from an URI relative to the playlist or music * Opens a playlist from an URI relative to the playlist or music
* directory. * directory.
*
* @param is_r on success, an input_stream object may be returned
* here, which must be closed after the playlist_provider object is
* freed
*/ */
struct playlist_provider * struct playlist_provider *
playlist_mapper_open(const char *uri); playlist_mapper_open(const char *uri, struct input_stream **is_r);
#endif #endif
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "song.h" #include "song.h"
#include "database.h" #include "database.h"
#include "client.h" #include "client.h"
#include "input_stream.h"
void void
playlist_print_uris(struct client *client, const struct playlist *playlist) playlist_print_uris(struct client *client, const struct playlist *playlist)
...@@ -168,11 +169,16 @@ playlist_provider_print(struct client *client, const char *uri, ...@@ -168,11 +169,16 @@ playlist_provider_print(struct client *client, const char *uri,
bool bool
playlist_file_print(struct client *client, const char *uri, bool detail) playlist_file_print(struct client *client, const char *uri, bool detail)
{ {
struct playlist_provider *playlist = playlist_mapper_open(uri); struct input_stream *is;
struct playlist_provider *playlist = playlist_mapper_open(uri, &is);
if (playlist == NULL) if (playlist == NULL)
return false; return false;
playlist_provider_print(client, uri, playlist, detail); playlist_provider_print(client, uri, playlist, detail);
playlist_plugin_close(playlist); playlist_plugin_close(playlist);
if (is != NULL)
input_stream_close(is);
return true; return true;
} }
...@@ -101,11 +101,16 @@ playlist_open_into_queue(const char *uri, struct playlist *dest) ...@@ -101,11 +101,16 @@ playlist_open_into_queue(const char *uri, struct playlist *dest)
if (uri_has_scheme(uri)) if (uri_has_scheme(uri))
return playlist_open_remote_into_queue(uri, dest); return playlist_open_remote_into_queue(uri, dest);
struct playlist_provider *playlist = playlist_mapper_open(uri); struct input_stream *is;
struct playlist_provider *playlist = playlist_mapper_open(uri, &is);
if (playlist != NULL) { if (playlist != NULL) {
enum playlist_result result = enum playlist_result result =
playlist_load_into_queue(uri, playlist, dest); playlist_load_into_queue(uri, playlist, dest);
playlist_plugin_close(playlist); playlist_plugin_close(playlist);
if (is != NULL)
input_stream_close(is);
return result; return result;
} }
......
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