diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ape.c | 4 | ||||
-rw-r--r-- | src/conf.c | 11 | ||||
-rw-r--r-- | src/database.c | 2 | ||||
-rw-r--r-- | src/decoder/ffmpeg_decoder_plugin.c | 54 | ||||
-rw-r--r-- | src/decoder/flac_metadata.c | 3 | ||||
-rw-r--r-- | src/decoder/flac_metadata.h | 3 | ||||
-rw-r--r-- | src/output/ao_plugin.c | 3 | ||||
-rw-r--r-- | src/output/httpd_output_plugin.c | 1 | ||||
-rw-r--r-- | src/output/recorder_output_plugin.c | 10 | ||||
-rw-r--r-- | src/output/shout_plugin.c | 28 | ||||
-rw-r--r-- | src/sticker.c | 4 |
11 files changed, 96 insertions, 27 deletions
@@ -60,8 +60,10 @@ ape_scan_internal(FILE *fp, tag_ape_callback_t callback, void *ctx) assert(remaining > 10); char *buffer = g_malloc(remaining); - if (fread(buffer, 1, remaining, fp) != remaining) + if (fread(buffer, 1, remaining, fp) != remaining) { + g_free(buffer); return false; + } /* read tags */ unsigned n = GUINT32_FROM_LE(footer.count); diff --git a/src/conf.c b/src/conf.c index fa05610ba..a79750477 100644 --- a/src/conf.c +++ b/src/conf.c @@ -372,6 +372,7 @@ config_read_file(const char *file, GError **error_r) assert(*line != 0); g_propagate_prefixed_error(error_r, error, "line %i: ", count); + fclose(fp); return false; } @@ -383,6 +384,7 @@ config_read_file(const char *file, GError **error_r) g_set_error(error_r, config_quark(), 0, "unrecognized parameter in config file at " "line %i: %s\n", count, name); + fclose(fp); return false; } @@ -392,6 +394,7 @@ config_read_file(const char *file, GError **error_r) "config parameter \"%s\" is first defined " "on line %i and redefined on line %i\n", name, param->line, count); + fclose(fp); return false; } @@ -403,6 +406,7 @@ config_read_file(const char *file, GError **error_r) if (*line != '{') { g_set_error(error_r, config_quark(), 0, "line %i: '{' expected", count); + fclose(fp); return false; } @@ -411,12 +415,15 @@ config_read_file(const char *file, GError **error_r) g_set_error(error_r, config_quark(), 0, "line %i: Unknown tokens after '{'", count); + fclose(fp); return false; } param = config_read_block(fp, &count, string, error_r); - if (param == NULL) + if (param == NULL) { + fclose(fp); return false; + } } else { /* a string value */ @@ -433,6 +440,7 @@ config_read_file(const char *file, GError **error_r) g_error_free(error); } + fclose(fp); return false; } @@ -440,6 +448,7 @@ config_read_file(const char *file, GError **error_r) g_set_error(error_r, config_quark(), 0, "line %i: Unknown tokens after value", count); + fclose(fp); return false; } diff --git a/src/database.c b/src/database.c index 8ded25635..660d9768a 100644 --- a/src/database.c +++ b/src/database.c @@ -180,7 +180,7 @@ db_check(void) } /* Check if we can write to the directory */ - if (access(dirPath, R_OK | W_OK)) { + if (access(dirPath, X_OK | W_OK)) { g_warning("Can't create db file in \"%s\": %s", dirPath, strerror(errno)); g_free(dirPath); diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 5f11683a0..78e874d9e 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -138,6 +138,33 @@ mpd_ffmpeg_stream_open(struct decoder *decoder, struct input_stream *input) return stream; } +/** + * API compatibility wrapper for av_open_input_stream() and + * avformat_open_input(). + */ +static int +mpd_ffmpeg_open_input(AVFormatContext **ic_ptr, +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,101,0) + AVIOContext *pb, +#else + ByteIOContext *pb, +#endif + const char *filename, + AVInputFormat *fmt) +{ +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,1,3) + AVFormatContext *context = avformat_alloc_context(); + if (context == NULL) + return AVERROR(ENOMEM); + + context->pb = pb; + *ic_ptr = context; + return avformat_open_input(ic_ptr, filename, fmt, NULL); +#else + return av_open_input_stream(ic_ptr, pb, filename, fmt, NULL); +#endif +} + static void mpd_ffmpeg_stream_close(struct mpd_ffmpeg_stream *stream) { @@ -317,9 +344,9 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) } //ffmpeg works with ours "fileops" helper - AVFormatContext *format_context; - if (av_open_input_stream(&format_context, stream->io, input->uri, - input_format, NULL) != 0) { + AVFormatContext *format_context = NULL; + if (mpd_ffmpeg_open_input(&format_context, stream->io, input->uri, + input_format) != 0) { g_warning("Open failed\n"); mpd_ffmpeg_stream_close(stream); return; @@ -441,13 +468,26 @@ static const ffmpeg_tag_map ffmpeg_tag_maps[] = { }; static bool -ffmpeg_copy_metadata(struct tag *tag, AVMetadata *m, +ffmpeg_copy_metadata(struct tag *tag, +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,1,0) + AVDictionary *m, +#else + AVMetadata *m, +#endif const ffmpeg_tag_map tag_map) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,1,0) + AVDictionaryEntry *mt = NULL; + + while ((mt = av_dict_get(m, tag_map.name, mt, 0)) != NULL) + tag_add_item(tag, tag_map.type, mt->value); +#else AVMetadataTag *mt = NULL; while ((mt = av_metadata_get(m, tag_map.name, mt, 0)) != NULL) tag_add_item(tag, tag_map.type, mt->value); +#endif + return mt != NULL; } @@ -463,9 +503,9 @@ ffmpeg_stream_tag(struct input_stream *is) if (stream == NULL) return NULL; - AVFormatContext *f; - if (av_open_input_stream(&f, stream->io, is->uri, - input_format, NULL) != 0) { + AVFormatContext *f = NULL; + if (mpd_ffmpeg_open_input(&f, stream->io, is->uri, + input_format) != 0) { mpd_ffmpeg_stream_close(stream); return NULL; } diff --git a/src/decoder/flac_metadata.c b/src/decoder/flac_metadata.c index 6987971c8..a19220572 100644 --- a/src/decoder/flac_metadata.c +++ b/src/decoder/flac_metadata.c @@ -224,7 +224,8 @@ flac_tag_apply_metadata(struct tag *tag, const char *track, break; case FLAC__METADATA_TYPE_STREAMINFO: - tag->time = flac_duration(&block->data.stream_info); + if (block->data.stream_info.sample_rate > 0) + tag->time = flac_duration(&block->data.stream_info); break; default: diff --git a/src/decoder/flac_metadata.h b/src/decoder/flac_metadata.h index 642a1d60d..01bc1924a 100644 --- a/src/decoder/flac_metadata.h +++ b/src/decoder/flac_metadata.h @@ -20,6 +20,7 @@ #ifndef MPD_FLAC_METADATA_H #define MPD_FLAC_METADATA_H +#include <assert.h> #include <stdbool.h> #include <FLAC/metadata.h> @@ -29,6 +30,8 @@ struct replay_gain_info; static inline unsigned flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) { + assert(stream_info->sample_rate > 0); + return (stream_info->total_samples + stream_info->sample_rate - 1) / stream_info->sample_rate; } diff --git a/src/output/ao_plugin.c b/src/output/ao_plugin.c index 71e06bad9..33366d3b8 100644 --- a/src/output/ao_plugin.c +++ b/src/output/ao_plugin.c @@ -106,12 +106,14 @@ ao_output_init(G_GNUC_UNUSED const struct audio_format *audio_format, g_set_error(error, ao_output_quark(), 0, "\"%s\" is not a valid ao driver", value); + g_free(ad); return NULL; } if ((ai = ao_driver_info(ad->driver)) == NULL) { g_set_error(error, ao_output_quark(), 0, "problems getting driver info"); + g_free(ad); return NULL; } @@ -129,6 +131,7 @@ ao_output_init(G_GNUC_UNUSED const struct audio_format *audio_format, g_set_error(error, ao_output_quark(), 0, "problems parsing options \"%s\"", options[i]); + g_free(ad); return NULL; } diff --git a/src/output/httpd_output_plugin.c b/src/output/httpd_output_plugin.c index 7fde676c5..20098c90e 100644 --- a/src/output/httpd_output_plugin.c +++ b/src/output/httpd_output_plugin.c @@ -103,6 +103,7 @@ httpd_output_init(G_GNUC_UNUSED const struct audio_format *audio_format, if (encoder_plugin == NULL) { g_set_error(error, httpd_output_quark(), 0, "No such encoder: %s", encoder_name); + g_free(httpd); return NULL; } diff --git a/src/output/recorder_output_plugin.c b/src/output/recorder_output_plugin.c index 346972a6b..070ef4b08 100644 --- a/src/output/recorder_output_plugin.c +++ b/src/output/recorder_output_plugin.c @@ -79,23 +79,27 @@ recorder_output_init(G_GNUC_UNUSED const struct audio_format *audio_format, if (encoder_plugin == NULL) { g_set_error(error_r, recorder_output_quark(), 0, "No such encoder: %s", encoder_name); - return NULL; + goto failure; } recorder->path = config_get_block_string(param, "path", NULL); if (recorder->path == NULL) { g_set_error(error_r, recorder_output_quark(), 0, "'path' not configured"); - return NULL; + goto failure; } /* initialize encoder */ recorder->encoder = encoder_init(encoder_plugin, param, error_r); if (recorder->encoder == NULL) - return NULL; + goto failure; return recorder; + +failure: + g_free(recorder); + return NULL; } static void diff --git a/src/output/shout_plugin.c b/src/output/shout_plugin.c index 484e47316..d808f48c6 100644 --- a/src/output/shout_plugin.c +++ b/src/output/shout_plugin.c @@ -152,7 +152,7 @@ my_shout_init_driver(const struct audio_format *audio_format, if (port == 0) { g_set_error(error, shout_output_quark(), 0, "shout port must be configured"); - return NULL; + goto failure; } check_block_param("password"); @@ -174,21 +174,21 @@ my_shout_init_driver(const struct audio_format *audio_format, "shout quality \"%s\" is not a number in the " "range -1 to 10, line %i", value, param->line); - return NULL; + goto failure; } if (config_get_block_string(param, "bitrate", NULL) != NULL) { g_set_error(error, shout_output_quark(), 0, "quality and bitrate are " "both defined"); - return NULL; + goto failure; } } else { value = config_get_block_string(param, "bitrate", NULL); if (value == NULL) { g_set_error(error, shout_output_quark(), 0, "neither bitrate nor quality defined"); - return NULL; + goto failure; } sd->bitrate = strtol(value, &test, 10); @@ -196,7 +196,7 @@ my_shout_init_driver(const struct audio_format *audio_format, if (*test != '\0' || sd->bitrate <= 0) { g_set_error(error, shout_output_quark(), 0, "bitrate must be a positive integer"); - return NULL; + goto failure; } } @@ -206,12 +206,12 @@ my_shout_init_driver(const struct audio_format *audio_format, g_set_error(error, shout_output_quark(), 0, "couldn't find shout encoder plugin \"%s\"", encoding); - return NULL; + goto failure; } sd->encoder = encoder_init(encoder_plugin, param, error); if (sd->encoder == NULL) - return NULL; + goto failure; if (strcmp(encoding, "mp3") == 0 || strcmp(encoding, "lame") == 0) shout_format = SHOUT_FORMAT_MP3; @@ -225,7 +225,7 @@ my_shout_init_driver(const struct audio_format *audio_format, g_set_error(error, shout_output_quark(), 0, "you cannot stream \"%s\" to shoutcast, use mp3", encoding); - return NULL; + goto failure; } else if (0 == strcmp(value, "shoutcast")) protocol = SHOUT_PROTOCOL_ICY; else if (0 == strcmp(value, "icecast1")) @@ -237,7 +237,7 @@ my_shout_init_driver(const struct audio_format *audio_format, "shout protocol \"%s\" is not \"shoutcast\" or " "\"icecast1\"or \"icecast2\"", value); - return NULL; + goto failure; } } else { protocol = SHOUT_PROTOCOL_HTTP; @@ -256,7 +256,7 @@ my_shout_init_driver(const struct audio_format *audio_format, shout_set_agent(sd->shout_conn, "MPD") != SHOUTERR_SUCCESS) { g_set_error(error, shout_output_quark(), 0, "%s", shout_get_error(sd->shout_conn)); - return NULL; + goto failure; } /* optional paramters */ @@ -267,14 +267,14 @@ my_shout_init_driver(const struct audio_format *audio_format, if (value != NULL && shout_set_genre(sd->shout_conn, value)) { g_set_error(error, shout_output_quark(), 0, "%s", shout_get_error(sd->shout_conn)); - return NULL; + goto failure; } value = config_get_block_string(param, "description", NULL); if (value != NULL && shout_set_description(sd->shout_conn, value)) { g_set_error(error, shout_output_quark(), 0, "%s", shout_get_error(sd->shout_conn)); - return NULL; + goto failure; } value = config_get_block_string(param, "url", NULL); @@ -307,6 +307,10 @@ my_shout_init_driver(const struct audio_format *audio_format, } return sd; + +failure: + free_shout_data(sd); + return NULL; } static bool diff --git a/src/sticker.c b/src/sticker.c index a17c11ba6..346a827a5 100644 --- a/src/sticker.c +++ b/src/sticker.c @@ -579,8 +579,10 @@ sticker_load(const char *type, const char *uri) bool success; success = sticker_list_values(sticker->table, type, uri); - if (!success) + if (!success) { + sticker_free(sticker); return NULL; + } if (g_hash_table_size(sticker->table) == 0) { /* don't return empty sticker objects */ |