From a59f1b21a6b302e5d42b00e8b6f3276979b683b4 Mon Sep 17 00:00:00 2001 From: vkostas Date: Sun, 7 Feb 2021 20:39:33 +0100 Subject: [PATCH 1/5] Fix: Separate Conductor from Performer Conductor was incorrectly saved to Performer tag in MPD database --- NEWS | 2 ++ src/tag/Id3Scan.cxx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8d0c6455a..6f2606b0e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.22.5 (not yet released) +* tags + - id: translate TPE3 to Conductor, not Performer * output - httpd: error handling on Windows improved diff --git a/src/tag/Id3Scan.cxx b/src/tag/Id3Scan.cxx index c2b9b7837..ef787f412 100644 --- a/src/tag/Id3Scan.cxx +++ b/src/tag/Id3Scan.cxx @@ -352,7 +352,7 @@ scan_id3_tag(const struct id3_tag *tag, TagHandler &handler) noexcept handler); tag_id3_import_text(tag, ID3_FRAME_COMPOSER, TAG_COMPOSER, handler); - tag_id3_import_text(tag, "TPE3", TAG_PERFORMER, + tag_id3_import_text(tag, "TPE3", TAG_CONDUCTOR, handler); tag_id3_import_text(tag, "TPE4", TAG_PERFORMER, handler); tag_id3_import_text(tag, "TIT1", TAG_GROUPING, handler); From 8695a2806ae7ac8d183b2056f4864b454959b830 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Feb 2021 21:16:55 +0100 Subject: [PATCH 2/5] test/run_input: document more options --- test/run_input.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/run_input.cxx b/test/run_input.cxx index 64eaa72cc..648efd6e1 100644 --- a/test/run_input.cxx +++ b/test/run_input.cxx @@ -118,7 +118,7 @@ ParseCommandLine(int argc, char **argv) auto args = option_parser.GetRemaining(); if (args.size != 1) - throw std::runtime_error("Usage: run_input [--verbose] [--config=FILE] URI"); + throw std::runtime_error("Usage: run_input [--verbose] [--config=FILE] [--scan] [--chunk-size=BYTES] URI"); c.uri = args.front(); return c; From c58c53293c28f3cfd5f3e37d9833887a64dba5c4 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Feb 2021 21:17:24 +0100 Subject: [PATCH 3/5] test/run_input: add option --seek --- test/run_input.cxx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/run_input.cxx b/test/run_input.cxx index 648efd6e1..0607dd3c6 100644 --- a/test/run_input.cxx +++ b/test/run_input.cxx @@ -56,6 +56,8 @@ struct CommandLine { FromNarrowPath config_path; + std::size_t seek = 0; + std::size_t chunk_size = MAX_CHUNK_SIZE; bool verbose = false; @@ -67,6 +69,7 @@ enum Option { OPTION_CONFIG, OPTION_VERBOSE, OPTION_SCAN, + OPTION_SEEK, OPTION_CHUNK_SIZE, }; @@ -74,6 +77,7 @@ static constexpr OptionDef option_defs[] = { {"config", 0, true, "Load a MPD configuration file"}, {"verbose", 'v', false, "Verbose logging"}, {"scan", 0, false, "Scan tags instead of reading raw data"}, + {"seek", 0, true, "Start reading at this position"}, {"chunk-size", 0, true, "Read this number of bytes at a time"}, }; @@ -108,6 +112,10 @@ ParseCommandLine(int argc, char **argv) c.scan = true; break; + case OPTION_SEEK: + c.seek = ParseSize(o.value); + break; + case OPTION_CHUNK_SIZE: c.chunk_size = ParseSize(o.value); if (c.chunk_size <= 0 || c.chunk_size > MAX_CHUNK_SIZE) @@ -153,10 +161,14 @@ tag_save(FILE *file, const Tag &tag) } static int -dump_input_stream(InputStream &is, FileDescriptor out, size_t chunk_size) +dump_input_stream(InputStream &is, FileDescriptor out, + offset_type seek, size_t chunk_size) { std::unique_lock lock(is.mutex); + if (seek > 0) + is.Seek(lock, seek); + /* print meta data */ if (is.HasMimeType()) @@ -256,7 +268,7 @@ try { Mutex mutex; auto is = InputStream::OpenReady(c.uri, mutex); return dump_input_stream(*is, FileDescriptor(STDOUT_FILENO), - c.chunk_size); + c.seek, c.chunk_size); } catch (...) { PrintException(std::current_exception()); return EXIT_FAILURE; From 4be76f3c8fd45b2bcbea661e69cf4f53588de88d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Feb 2021 21:24:47 +0100 Subject: [PATCH 4/5] archive/iso9660: check "skip==0" before doing optimized large read After a Seek() to an odd offset, some data needs to be skipped from the start of the block, and reading right into the given buffer doesn't work. --- src/archive/plugins/Iso9660ArchivePlugin.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx index f0123e58f..56bf15c28 100644 --- a/src/archive/plugins/Iso9660ArchivePlugin.cxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx @@ -266,7 +266,7 @@ Iso9660InputStream::Read(std::unique_lock &, const lsn_t read_lsn = lsn + offset / ISO_BLOCKSIZE; - if (read_size >= ISO_BLOCKSIZE) { + if (read_size >= ISO_BLOCKSIZE && skip == 0) { /* big read - read right into the caller's buffer */ auto nbytes = iso->SeekRead(ptr, read_lsn, From e7da5b104d440940aad897567d0b54009eae4a84 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 7 Feb 2021 21:24:19 +0100 Subject: [PATCH 5/5] archive/iso9660: another fix for unaligned reads Commit 79b2366387dcd5f4ccae50eacf1ae06973f01d83 added the field `skip` to support unaligned reads, but set the `offset` field to a wrong value. This resulted in miscalculation of `remaining`, causing an assertion failure. The fix is to assign `offset` the correct value, but consider the `skip` value in the assertion. Closes https://github.com/MusicPlayerDaemon/MPD/issues/1067 --- NEWS | 2 ++ src/archive/plugins/Iso9660ArchivePlugin.cxx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 6f2606b0e..9bb3f60a0 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.22.5 (not yet released) * tags - id: translate TPE3 to Conductor, not Performer +* archive + - iso9660: another fix for unaligned reads * output - httpd: error handling on Windows improved diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx index 56bf15c28..71f2ebb22 100644 --- a/src/archive/plugins/Iso9660ArchivePlugin.cxx +++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx @@ -221,8 +221,8 @@ public: if (new_offset > size) throw std::runtime_error("Invalid seek offset"); + offset = new_offset; skip = new_offset % ISO_BLOCKSIZE; - offset = new_offset - skip; buffer.Clear(); } }; @@ -260,7 +260,7 @@ Iso9660InputStream::Read(std::unique_lock &, if (r.empty()) { /* the buffer is empty - read more data from the ISO file */ - assert(offset % ISO_BLOCKSIZE == 0); + assert((offset - skip) % ISO_BLOCKSIZE == 0); const ScopeUnlock unlock(mutex);