Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libopenmpt for openSUSE:Factory checked in at 2021-04-08 21:01:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libopenmpt (Old) and /work/SRC/openSUSE:Factory/.libopenmpt.new.2401 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libopenmpt" Thu Apr 8 21:01:17 2021 rev:28 rq:880307 version:0.5.7 Changes: -------- --- /work/SRC/openSUSE:Factory/libopenmpt/libopenmpt.changes 2021-02-07 15:17:50.477649832 +0100 +++ /work/SRC/openSUSE:Factory/.libopenmpt.new.2401/libopenmpt.changes 2021-04-08 21:01:18.329844903 +0200 @@ -1,0 +2,24 @@ +Sat Mar 20 20:15:48 UTC 2021 - Mia Herkt <[email protected]> + +- Update to 0.5.7: + * [Sec] Possible null-pointer dereference read caused by a + sequence of openmpt::module::read, + openmpt::module::set_position_seconds with a position past the + song end, and another openmpt::module::read call. + + * IT: Instrument / sample panning was reset on note-off / fade + commands. + * IMF: Set Finetune is now implemented correctly. + * Fixed excessive memory consumption with malformed files in + various formats. + +------------------------------------------------------------------- +Sun Mar 14 18:40:46 UTC 2021 - Mia Herkt <[email protected]> + +- Update to 0.5.6: + * AMS: Avoid allocating excessive amount of memory for compressed + song message in malformed files. + * S3M: Some samples or OPL patches were imported with a too high + sample rate if module was saved with Scream Tracker 3. + +------------------------------------------------------------------- Old: ---- libopenmpt-0.5.5+release.autotools.tar.gz New: ---- libopenmpt-0.5.7+release.autotools.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libopenmpt.spec ++++++ --- /var/tmp/diff_new_pack.KPT9B1/_old 2021-04-08 21:01:19.633846312 +0200 +++ /var/tmp/diff_new_pack.KPT9B1/_new 2021-04-08 21:01:19.637846316 +0200 @@ -21,7 +21,7 @@ %define libopenmpt_modplug_version 0.8.9.0 Name: libopenmpt -Version: 0.5.5 +Version: 0.5.7 Release: 0 Summary: C++ and C library to decode tracker music files License: BSD-3-Clause ++++++ libopenmpt-0.5.5+release.autotools.tar.gz -> libopenmpt-0.5.7+release.autotools.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/common/versionNumber.h new/libopenmpt-0.5.7+release.autotools/common/versionNumber.h --- old/libopenmpt-0.5.5+release.autotools/common/versionNumber.h 2021-01-31 14:55:27.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/common/versionNumber.h 2021-03-20 18:05:10.000000000 +0100 @@ -17,7 +17,7 @@ // Version definitions. The only thing that needs to be changed when changing version number. #define VER_MAJORMAJOR 1 #define VER_MAJOR 29 -#define VER_MINOR 07 -#define VER_MINORMINOR 00 +#define VER_MINOR 08 +#define VER_MINORMINOR 03 OPENMPT_NAMESPACE_END diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/configure new/libopenmpt-0.5.7+release.autotools/configure --- old/libopenmpt-0.5.5+release.autotools/configure 2021-01-31 15:18:44.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/configure 2021-03-20 18:09:44.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libopenmpt 0.5.5+release.autotools. +# Generated by GNU Autoconf 2.69 for libopenmpt 0.5.7+release.autotools. # # Report bugs to <https://bugs.openmpt.org/>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='libopenmpt' PACKAGE_TARNAME='libopenmpt' -PACKAGE_VERSION='0.5.5+release.autotools' -PACKAGE_STRING='libopenmpt 0.5.5+release.autotools' +PACKAGE_VERSION='0.5.7+release.autotools' +PACKAGE_STRING='libopenmpt 0.5.7+release.autotools' PACKAGE_BUGREPORT='https://bugs.openmpt.org/' PACKAGE_URL='https://lib.openmpt.org/' @@ -1472,7 +1472,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libopenmpt 0.5.5+release.autotools to adapt to many kinds of systems. +\`configure' configures libopenmpt 0.5.7+release.autotools to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1543,7 +1543,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libopenmpt 0.5.5+release.autotools:";; + short | recursive ) echo "Configuration of libopenmpt 0.5.7+release.autotools:";; esac cat <<\_ACEOF @@ -1729,7 +1729,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libopenmpt configure 0.5.5+release.autotools +libopenmpt configure 0.5.7+release.autotools generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2219,7 +2219,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libopenmpt $as_me 0.5.5+release.autotools, which was +It was created by libopenmpt $as_me 0.5.7+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3090,7 +3090,7 @@ # Define the identity of the package. PACKAGE='libopenmpt' - VERSION='0.5.5+release.autotools' + VERSION='0.5.7+release.autotools' cat >>confdefs.h <<_ACEOF @@ -17251,13 +17251,13 @@ -$as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.5\"" >>confdefs.h +$as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.7\"" >>confdefs.h -$as_echo "#define MPT_SVNVERSION \"14111\"" >>confdefs.h +$as_echo "#define MPT_SVNVERSION \"14391\"" >>confdefs.h -$as_echo "#define MPT_SVNDATE \"2021-01-31T14:15:03.175335Z\"" >>confdefs.h +$as_echo "#define MPT_SVNDATE \"2021-03-20T17:06:12.434258Z\"" >>confdefs.h $as_echo "#define MPT_PACKAGE true" >>confdefs.h @@ -18222,9 +18222,9 @@ fi else - have_portaudicppo=0 + have_portaudiocpp=0 fi - if test x$have_portaudio = x1; then + if test x$have_portaudiocpp = x1; then HAVE_PORTAUDIOCPP_TRUE= HAVE_PORTAUDIOCPP_FALSE='#' else @@ -22522,7 +22522,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libopenmpt $as_me 0.5.5+release.autotools, which was +This file was extended by libopenmpt $as_me 0.5.7+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22589,7 +22589,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libopenmpt config.status 0.5.5+release.autotools +libopenmpt config.status 0.5.7+release.autotools configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/configure.ac new/libopenmpt-0.5.7+release.autotools/configure.ac --- old/libopenmpt-0.5.5+release.autotools/configure.ac 2021-01-31 15:18:32.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/configure.ac 2021-03-20 18:09:34.000000000 +0100 @@ -1,4 +1,4 @@ -AC_INIT([libopenmpt], [0.5.5+release.autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/]) +AC_INIT([libopenmpt], [0.5.7+release.autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/]) AC_PREREQ([2.68]) AC_CONFIG_MACRO_DIR([m4]) @@ -27,9 +27,9 @@ AC_SUBST([LIBOPENMPT_LTVER_REVISION]) AC_SUBST([LIBOPENMPT_LTVER_AGE]) -AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.5"], [svn version]) -AC_DEFINE([MPT_SVNVERSION], ["14111"], [svn version]) -AC_DEFINE([MPT_SVNDATE], ["2021-01-31T14:15:03.175335Z"], [svn date]) +AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.7"], [svn version]) +AC_DEFINE([MPT_SVNVERSION], ["14391"], [svn version]) +AC_DEFINE([MPT_SVNDATE], ["2021-03-20T17:06:12.434258Z"], [svn date]) AC_DEFINE([MPT_PACKAGE], [true], [is package]) @@ -236,8 +236,8 @@ have_portaudiocpp=0 ] ) -],[have_portaudicppo=0]) -AM_CONDITIONAL([HAVE_PORTAUDIOCPP], [test x$have_portaudio = x1]) +],[have_portaudiocpp=0]) +AM_CONDITIONAL([HAVE_PORTAUDIOCPP], [test x$have_portaudiocpp = x1]) # Optional disabled openmpt123 dependency: libsdl2 AC_ARG_WITH([sdl2], AS_HELP_STRING([--with-sdl2], [Enable use of libsdl2.])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/libopenmpt/dox/changelog.md new/libopenmpt-0.5.7+release.autotools/libopenmpt/dox/changelog.md --- old/libopenmpt-0.5.5+release.autotools/libopenmpt/dox/changelog.md 2021-01-31 15:15:00.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/libopenmpt/dox/changelog.md 2021-03-20 18:06:09.000000000 +0100 @@ -5,6 +5,26 @@ For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.5.7 (2021-03-20) + + * [**Sec**] Possible null-pointer dereference read caused by a sequence of + `openmpt::module::read`, `openmpt::module::set_position_seconds` with a + position past the song end, and another `openmpt::module::read` call. + (r14363) + + * IT: Instrument / sample panning was reset on note-off / fade commands. + * IMF: Set Finetune is now implemented correctly. + * Fixed excessive memory consumption with malformed files in various formats. + +### libopenmpt 0.5.6 (2021-03-14) + + * AMS: Avoid allocating excessive amount of memory for compressed song message + in malformed files. + * S3M: Some samples or OPL patches were imported with a too high sample rate + if module was saved with Scream Tracker 3. + + * vorbis: Update to v1.3.7 (2020-07-04). + ### libopenmpt 0.5.5 (2021-01-31) * [**New**] `Makefile` `CONFIG=emscripten` now supports diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/libopenmpt/dox/dependencies.md new/libopenmpt-0.5.7+release.autotools/libopenmpt/dox/dependencies.md --- old/libopenmpt-0.5.5+release.autotools/libopenmpt/dox/dependencies.md 2020-07-31 09:12:54.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/libopenmpt/dox/dependencies.md 2021-03-20 13:38:33.000000000 +0100 @@ -24,7 +24,6 @@ used for building: * `std::numeric_limits<unsigned char>::digits == 8` (enforced by static_assert) - * `sizeof(char) == 1` (enforced by static_assert) * existence of `std::uintptr_t` (enforced by static_assert) * in C++20 mode, `std::endian::little != std::endian::big` (enforced by static_assert) @@ -33,8 +32,6 @@ assumed) * representation of basic source character set is identical in char and `wchar_t` (implicitly assumed) - * libopenmpt also has experimental support for platforms without - `wchar_t` support like DJGPP libopenmpt does not rely on any specific implementation defined or undefined behaviour (if it does, that's a bug in libopenmpt). In @@ -43,23 +40,26 @@ * shifting signed values is implementation defined * `signed` integer overflow is undefined * `float` and `double` can be non-IEEE754 + + libopenmpt can optionally support for certain incomplete C++ + implementations: + * platforms without `wchar_t` support (like DJGPP) + * platforms without working `std::random_device` (like Emscripten when + running in `AudioWorkletProcessor` context) + * platforms without working `std::high_resolution_clock` (like + Emscripten when running in `AudioWorkletProcessor` context) * Required compilers to use libopenmpt: * Any **C89** / **C99** / **C11** compatible compiler should work with the C API as long as a **C99** compatible **stdint.h** is available. * Any **C++17** compatible compiler should work with the C++ API. * **J2B** support requires an inflate (deflate decompression) implementation: - * **zlib** - * **miniz** can be used internally if no zlib is available. - * Built-in **MO3** support requires: - * **libmpg123 >= 1.14.0** - * **libogg** - * **libvorbis** - * **libvorbisfile** - * Instead of libmpg123, **minimp3 by Lion (github.com/lieff)** can be used - internally to decode MP3 samples. - * Instead of libogg, libvorbis and libvorbisfile, **stb_vorbis** can be - used internally to decode Vorbis samples. + * **zlib** (or **miniz** can be used internally) + * **MO3** support requires: + * **libmpg123 >= 1.14.0** (or **minimp3 by Lion (github.com/lieff)** can + be used internally) + * **libogg**, **libvorbis**, and **libvorbisfile** (or **stb_vorbis** can + be used internally) * Building on Unix-like systems requires: * **GNU make** * **pkg-config** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_impl.cpp new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_impl.cpp --- old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_impl.cpp 2021-01-03 00:13:06.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_impl.cpp 2021-03-19 23:26:41.000000000 +0100 @@ -66,8 +66,8 @@ MPT_WARNING("Warning: Building libopenmpt with MinGW-w64 without std::thread support is not recommended and is deprecated. Please use MinGW-w64 with posix threading model (as opposed to win32 threading model), or build with mingw-std-threads.") #endif // MINGW -#if MPT_CLANG_AT_LEAST(5,0,0) && defined(__powerpc__) && !defined(__powerpc64__) -MPT_WARNING("Warning: libopenmpt is known to trigger bad code generation with Clang 5 or later on powerpc (32bit) when using -O3. See <https://bugs.llvm.org/show_bug.cgi?id=46683>.") +#if MPT_CLANG_AT_LEAST(5,0,0) && MPT_CLANG_BEFORE(11,0,0) && defined(__powerpc__) && !defined(__powerpc64__) +MPT_WARNING("Warning: libopenmpt is known to trigger bad code generation with Clang 5..10 on powerpc (32bit) when using -O3. See <https://bugs.llvm.org/show_bug.cgi?id=46683>.") #endif #endif // !MPT_BUILD_SILENCE_LIBOPENMPT_CONFIGURATION_WARNINGS @@ -1108,8 +1108,9 @@ } m_sndFile->SetCurrentOrder( static_cast<ORDERINDEX>( subsong->start_order ) ); GetLengthType t = m_sndFile->GetLength( m_ctl_seek_sync_samples ? eAdjustSamplePositions : eAdjust, GetLengthTarget( seconds ).StartPos( static_cast<SEQUENCEINDEX>( subsong->sequence ), static_cast<ORDERINDEX>( subsong->start_order ), static_cast<ROWINDEX>( subsong->start_row ) ) ).back(); - m_sndFile->m_PlayState.m_nNextOrder = m_sndFile->m_PlayState.m_nCurrentOrder = t.lastOrder; - m_sndFile->m_PlayState.m_nNextRow = t.lastRow; + m_sndFile->m_PlayState.m_nNextOrder = m_sndFile->m_PlayState.m_nCurrentOrder = t.targetReached ? t.lastOrder : t.endOrder; + m_sndFile->m_PlayState.m_nNextRow = t.targetReached ? t.lastRow : t.endRow; + m_sndFile->m_PlayState.m_nTickCount = Util::MaxValueOfType(m_sndFile->m_PlayState.m_nTickCount) - 1; m_currentPositionSeconds = base_seconds + t.duration; return m_currentPositionSeconds; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_version.h new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_version.h --- old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_version.h 2021-01-31 15:15:00.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_version.h 2021-03-20 18:06:09.000000000 +0100 @@ -19,7 +19,7 @@ /*! \brief libopenmpt minor version number */ #define OPENMPT_API_VERSION_MINOR 5 /*! \brief libopenmpt patch version number */ -#define OPENMPT_API_VERSION_PATCH 5 +#define OPENMPT_API_VERSION_PATCH 7 /*! \brief libopenmpt pre-release tag */ #define OPENMPT_API_VERSION_PREREL "" /*! \brief libopenmpt pre-release flag */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_version.mk new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_version.mk --- old/libopenmpt-0.5.5+release.autotools/libopenmpt/libopenmpt_version.mk 2021-01-31 15:15:00.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/libopenmpt/libopenmpt_version.mk 2021-03-20 18:06:09.000000000 +0100 @@ -1,8 +1,8 @@ LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=5 -LIBOPENMPT_VERSION_PATCH=5 +LIBOPENMPT_VERSION_PATCH=7 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=2 -LIBOPENMPT_LTVER_REVISION=5 +LIBOPENMPT_LTVER_REVISION=7 LIBOPENMPT_LTVER_AGE=2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/man/openmpt123.1 new/libopenmpt-0.5.7+release.autotools/man/openmpt123.1 --- old/libopenmpt-0.5.5+release.autotools/man/openmpt123.1 2021-01-31 15:18:32.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/man/openmpt123.1 2021-03-20 18:09:34.000000000 +0100 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8. -.TH OPENMPT123 "1" "January 2021" "openmpt123 v0.5.5" "User Commands" +.TH OPENMPT123 "1" "March 2021" "openmpt123 v0.5.7" "User Commands" .SH NAME openmpt123 - command line module music player based on libopenmpt .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/openmpt123/openmpt123.cpp new/libopenmpt-0.5.7+release.autotools/openmpt123/openmpt123.cpp --- old/libopenmpt-0.5.5+release.autotools/openmpt123/openmpt123.cpp 2021-01-01 09:06:03.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/openmpt123/openmpt123.cpp 2021-02-24 16:08:09.000000000 +0100 @@ -74,6 +74,7 @@ #include <conio.h> #include <fcntl.h> #include <io.h> +#include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <windows.h> @@ -2288,9 +2289,14 @@ #endif textout_dummy dummy_log; #if defined(WIN32) +#if defined(UNICODE) textout_ostream_console std_out( std::wcout, STD_OUTPUT_HANDLE ); textout_ostream_console std_err( std::wclog, STD_ERROR_HANDLE ); #else + textout_ostream_console std_out( std::cout, STD_OUTPUT_HANDLE ); + textout_ostream_console std_err( std::clog, STD_ERROR_HANDLE ); +#endif +#else textout_ostream std_out( std::cout ); textout_ostream std_err( std::clog ); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/openmpt123/openmpt123.hpp new/libopenmpt-0.5.7+release.autotools/openmpt123/openmpt123.hpp --- old/libopenmpt-0.5.5+release.autotools/openmpt123/openmpt123.hpp 2020-04-28 18:22:54.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/openmpt123/openmpt123.hpp 2021-02-24 16:08:09.000000000 +0100 @@ -890,11 +890,19 @@ class textout_ostream_console : public textout { private: +#if defined(UNICODE) std::wostream & s; +#else + std::ostream & s; +#endif HANDLE handle; bool console; public: +#if defined(UNICODE) textout_ostream_console( std::wostream & s_, DWORD stdHandle_ ) +#else + textout_ostream_console( std::ostream & s_, DWORD stdHandle_ ) +#endif : s(s_) , handle(GetStdHandle( stdHandle_ )) , console(IsConsole( stdHandle_ )) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/ContainerUMX.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/ContainerUMX.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/ContainerUMX.cpp 2019-11-02 10:13:50.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/ContainerUMX.cpp 2021-03-16 23:51:41.000000000 +0100 @@ -77,8 +77,9 @@ } std::vector<int32> classes; - classes.reserve(fileHeader.importCount); - for(uint32 i = 0; i < fileHeader.importCount && file.CanRead(4); i++) + const uint32 importCount = std::min(fileHeader.importCount.get(), mpt::saturate_cast<uint32>(file.BytesLeft() / 4u)); + classes.reserve(importCount); + for(uint32 i = 0; i < importCount && file.CanRead(4); i++) { int32 objName = ReadUMXImportTableEntry(file, fileHeader.packageVersion); if(static_cast<size_t>(objName) < names.size()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_ams.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_ams.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_ams.cpp 2020-04-20 22:38:06.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_ams.cpp 2021-03-13 23:36:35.000000000 +0100 @@ -903,12 +903,9 @@ // Text // Read composer name - uint8 composerLength = file.ReadUint8(); - if(composerLength) + if(std::string composer; file.ReadSizedString<uint8le, mpt::String::spacePadded>(composer)) { - std::string str; - file.ReadString<mpt::String::spacePadded>(str, composerLength); - m_songArtist = mpt::ToUnicode(mpt::Charset::CP437AMS2, str); + m_songArtist = mpt::ToUnicode(mpt::Charset::CP437AMS2, composer); } // Channel names @@ -926,11 +923,13 @@ } if(descriptionHeader.packedLen > sizeof(descriptionHeader) && file.CanRead(descriptionHeader.packedLen - sizeof(descriptionHeader))) { - const size_t textLength = descriptionHeader.packedLen - sizeof(descriptionHeader); + const uint32 textLength = descriptionHeader.packedLen - static_cast<uint32>(sizeof(descriptionHeader)); std::vector<uint8> textIn; file.ReadVector(textIn, textLength); + // In the best case, every byte triplet can decode to 255 bytes, which is a ratio of exactly 1:85 + const uint32 maxLength = std::min(textLength, Util::MaxValueOfType(textLength) / 85u) * 85u; std::string textOut; - textOut.reserve(descriptionHeader.unpackedLen); + textOut.reserve(std::min(maxLength, descriptionHeader.unpackedLen.get())); size_t readLen = 0; while(readLen < textLength) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_c67.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_c67.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_c67.cpp 2019-12-24 10:29:44.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_c67.cpp 2021-03-20 14:08:00.000000000 +0100 @@ -168,6 +168,7 @@ m_nSamples = 64; m_nChannels = 4 + 9; m_playBehaviour.set(kOPLBeatingOscillators); + m_SongFlags.set(SONG_IMPORTED); // Pan PCM channels only for(CHANNELINDEX chn = 0; chn < 4; chn++) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_dmf.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_dmf.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_dmf.cpp 2021-01-25 20:58:24.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_dmf.cpp 2021-03-20 14:30:01.000000000 +0100 @@ -934,10 +934,10 @@ file.Read(chunkHeader); uint32 chunkLength = chunkHeader.length, chunkSkip = 0; // When loop start was added to version 3, the chunk size was not updated... - if(fileHeader.version == 3 && chunkHeader.GetID() == DMFChunk::idSEQU && chunkLength < uint32_max - 2) + if(fileHeader.version == 3 && chunkHeader.GetID() == DMFChunk::idSEQU) chunkSkip = 2; // ...and when the loop end was added to version 4, it was also note updated! Luckily they fixed it in version 5. - else if(fileHeader.version == 4 && chunkHeader.GetID() == DMFChunk::idSEQU && chunkLength < uint32_max - 4) + else if(fileHeader.version == 4 && chunkHeader.GetID() == DMFChunk::idSEQU) chunkSkip = 4; // Earlier X-Tracker versions also write a garbage length for the SMPD chunk if samples are compressed. // I don't know when exactly this stopped, but I have no version 5-7 files to check (and no X-Tracker version that writes those versions). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_gdm.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_gdm.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_gdm.cpp 2019-12-24 10:29:44.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_gdm.cpp 2021-03-20 14:08:00.000000000 +0100 @@ -163,6 +163,7 @@ } InitializeGlobals(gdmFormatOrigin[fileHeader.originalFormat]); + m_SongFlags.set(SONG_IMPORTED); m_modFormat.formatName = U_("General Digital Music"); m_modFormat.type = U_("gdm"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_it.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_it.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_it.cpp 2020-08-27 18:36:37.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_it.cpp 2021-03-16 00:06:26.000000000 +0100 @@ -2086,19 +2086,11 @@ plugin.editorX = plugin.editorY = int32_min; // Plugin user data - const uint32 pluginDataChunkSize = file.ReadUint32LE(); - FileReader pluginDataChunk = file.ReadChunk(pluginDataChunkSize); + FileReader pluginDataChunk = file.ReadChunk(file.ReadUint32LE()); + plugin.pluginData.resize(mpt::saturate_cast<size_t>(pluginDataChunk.BytesLeft())); + pluginDataChunk.ReadRaw(mpt::as_span(plugin.pluginData)); - if(pluginDataChunk.IsValid()) - { - plugin.pluginData.resize(pluginDataChunkSize); - pluginDataChunk.ReadRaw(plugin.pluginData.data(), pluginDataChunkSize); - } - - FileReader modularData = file.ReadChunk(file.ReadUint32LE()); - - //if dwMPTExtra is positive and there are dwMPTExtra bytes left in nPluginSize, we have some more data! - if(modularData.IsValid()) + if(FileReader modularData = file.ReadChunk(file.ReadUint32LE()); modularData.IsValid()) { while(modularData.CanRead(5)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_itp.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_itp.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_itp.cpp 2019-11-02 10:13:50.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_itp.cpp 2021-03-20 14:08:00.000000000 +0100 @@ -160,6 +160,7 @@ { return false; } + m_SongFlags.set(SONG_IMPORTED); if(songFlags & ITP_ITOLDEFFECTS) m_SongFlags.set(SONG_ITOLDEFFECTS); if(songFlags & ITP_ITCOMPATGXX) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_mo3.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_mo3.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_mo3.cpp 2020-10-19 23:10:24.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_mo3.cpp 2021-03-20 14:08:00.000000000 +0100 @@ -399,40 +399,38 @@ } while(carry); \ } -static bool UnpackMO3Data(FileReader &file, uint8 *dst, uint32 size) + +static bool UnpackMO3Data(FileReader &file, std::vector<uint8> &uncompressed, const uint32 size) { if(!size) - { return false; - } uint16 data = 0; int8 carry = 0; // x86 carry (used to propagate the most significant bit from one byte to another) int32 strLen = 0; // length of previous string int32 strOffset; // string offset - uint8 *initDst = dst; - uint32 ebp, previousPtr = 0; - uint32 initSize = size; + uint32 previousPtr = 0; // Read first uncompressed byte - *dst++ = file.ReadUint8(); - size--; + uncompressed.push_back(file.ReadUint8()); + uint32 remain = size - 1; - while(size > 0) + while(remain > 0) { READ_CTRL_BIT; if(!carry) { // a 0 ctrl bit means 'copy', not compressed byte - if(!file.Read(*dst)) + if(uint8 b; file.Read(b)) + uncompressed.push_back(b); + else break; - dst++; - size--; + remain--; } else { // a 1 ctrl bit means compressed bytes are following - ebp = 0; // length adjustment - DECODE_CTRL_BITS; // read length, and if strLen > 3 (coded using more than 1 bits pair) also part of the offset value + uint8 lengthAdjust = 0; // length adjustment + DECODE_CTRL_BITS; // read length, and if strLen > 3 (coded using more than 1 bits pair) also part of the offset value strLen -= 3; if(strLen < 0) { @@ -442,17 +440,17 @@ } else { // LZ ptr in ctrl stream - uint8 b; - if(!file.Read(b)) + if(uint8 b; file.Read(b)) + strOffset = (strLen << 8) | b; // read less significant offset byte from stream + else break; - strOffset = (strLen << 8) | b; // read less significant offset byte from stream strLen = 0; strOffset = ~strOffset; if(strOffset < -1280) - ebp++; - ebp++; // length is always at least 1 + lengthAdjust++; + lengthAdjust++; // length is always at least 1 if(strOffset < -32000) - ebp++; + lengthAdjust++; previousPtr = strOffset; // save current Ptr } @@ -467,36 +465,33 @@ DECODE_CTRL_BITS; // decode length: 1 is the most significant bit, strLen += 2; // then first bit of each bits pairs (noted n1), until n0. } - strLen += ebp; // length adjustment - if(size >= static_cast<uint32>(strLen) && strLen > 0) - { - // Copy previous string - if(strOffset >= 0 || static_cast<std::ptrdiff_t>(dst - initDst) + strOffset < 0) - { - break; - } - size -= strLen; - const uint8 *string = dst + strOffset; - while(strLen > 0) - { - *dst++ = *string++; - strLen--; - } - } else - { + strLen += lengthAdjust; // length adjustment + + if(remain < static_cast<uint32>(strLen) || strLen <= 0) break; - } + if(strOffset >= 0 || -static_cast<ptrdiff_t>(uncompressed.size()) > strOffset) + break; + + // Copy previous string + // Need to do this in two steps as source and destination may overlap (e.g. strOffset = -1, strLen = 2 repeats last character twice) + uncompressed.insert(uncompressed.end(), strLen, 0); + remain -= strLen; + auto src = uncompressed.cend() - strLen + strOffset; + auto dst = uncompressed.end() - strLen; + do + { + strLen--; + *dst++ = *src++; + } while(strLen > 0); } } #ifdef MPT_BUILD_FUZZER // When using a fuzzer, we should not care if the decompressed buffer has the correct size. // This makes finding new interesting test cases much easier. - while(size-- > 0) - { - *dst++ = 0; - } + return true; +#else + return remain == 0; #endif // MPT_BUILD_FUZZER - return (dst - initDst) == static_cast<std::ptrdiff_t>(initSize); } @@ -742,7 +737,7 @@ { return false; } - if(containerHeader.musicSize <= sizeof(MO3FileHeader)) + if(containerHeader.musicSize <= sizeof(MO3FileHeader) || containerHeader.musicSize >= uint32_max / 2u) { return false; } @@ -789,24 +784,25 @@ } const uint8 version = containerHeader.version; - const uint32 musicSize = containerHeader.musicSize; - uint32 compressedSize = uint32_max; + uint32 compressedSize = uint32_max, reserveSize = 1024 * 1024; // Generous estimate based on biggest pre-v5 MO3s found in the wild (~350K music data) if(version >= 5) { // Size of compressed music chunk compressedSize = file.ReadUint32LE(); -#ifndef MPT_BUILD_FUZZER if(!file.CanRead(compressedSize)) - { return false; - } -#endif // !MPT_BUILD_FUZZER + // Generous estimate based on highest real-world compression ratio I found in a module (~20:1) + reserveSize = std::min(Util::MaxValueOfType(reserveSize) / 32u, compressedSize) * 32u; } - std::vector<uint8> musicData(musicSize); - - if(!UnpackMO3Data(file, musicData.data(), musicSize)) + std::vector<uint8> musicData; + // We don't always reserve the whole uncompressed size as claimed by the module to guard against broken files + // that e.g. claim that the uncompressed size is 1GB while the MO3 file itself is only 100 bytes. + // As the LZ compression used in MO3 doesn't allow for establishing a clear upper bound for the maximum size, + // this is probably the only sensible way we can prevent DoS due to huge allocations. + musicData.reserve(std::min(reserveSize, containerHeader.musicSize.get())); + if(!UnpackMO3Data(file, musicData, containerHeader.musicSize)) { return false; } @@ -849,6 +845,7 @@ else SetType(MOD_TYPE_XM); + m_SongFlags.set(SONG_IMPORTED); if(fileHeader.flags & MO3FileHeader::linearSlides) m_SongFlags.set(SONG_LINEARSLIDES); if((fileHeader.flags & MO3FileHeader::s3mAmigaLimits) && m_nType == MOD_TYPE_S3M) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_mod.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_mod.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_mod.cpp 2021-01-04 19:04:45.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_mod.cpp 2021-03-20 14:08:00.000000000 +0100 @@ -1951,7 +1951,7 @@ m_nMinPeriod = 14 * 4; m_nMaxPeriod = 3424 * 4; m_nSamplePreAmp = 64; - m_SongFlags.set(SONG_PT_MODE); + m_SongFlags.set(SONG_PT_MODE | SONG_IMPORTED); // Setup channel pan positions and volume SetupMODPanning(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_s3m.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_s3m.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_s3m.cpp 2020-07-15 20:07:36.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_s3m.cpp 2021-02-13 20:57:13.000000000 +0100 @@ -84,6 +84,7 @@ case CMD_TONEPORTAVOL: command = 'L'; break; case CMD_CHANNELVOLUME: command = 'M'; break; case CMD_CHANNELVOLSLIDE: command = 'N'; break; + case CMD_OFFSETPERCENTAGE: case CMD_OFFSET: command = 'O'; break; case CMD_PANNINGSLIDE: command = 'P'; break; case CMD_RETRIG: command = 'Q'; break; @@ -465,7 +466,7 @@ continue; } - sampleHeader.ConvertToMPT(Samples[smp + 1]); + sampleHeader.ConvertToMPT(Samples[smp + 1], isST3); m_szNames[smp + 1] = mpt::String::ReadBuf(mpt::String::nullTerminated, sampleHeader.name); if(sampleHeader.sampleType < S3MSampleHeader::typeAdMel) @@ -527,7 +528,7 @@ } CHANNELINDEX channel = (info & s3mChannelMask); - ModCommand dummy = ModCommand::Empty(); + ModCommand dummy; ModCommand &m = (channel < GetNumChannels()) ? rowBase[channel] : dummy; if(info & s3mNotePresent) @@ -577,12 +578,9 @@ } else { if(m.param < 0x08) - { zxxCountLeft++; - } else if(m.param > 0x08) - { + else if(m.param > 0x08) zxxCountRight++; - } } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_stp.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_stp.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_stp.cpp 2020-10-19 23:01:24.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_stp.cpp 2021-03-17 19:51:21.000000000 +0100 @@ -333,7 +333,9 @@ STPLoopList &loopList = loopInfo[actualSmp - 1]; loopList.clear(); - uint16 numLoops = file.ReadUint16BE(); + const uint16 numLoops = file.ReadUint16BE(); + if(!file.CanRead(numLoops * 8u)) + return false; loopList.reserve(numLoops); STPLoopInfo loop; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_uax.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_uax.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_uax.cpp 2020-10-19 23:01:24.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_uax.cpp 2021-03-16 23:51:41.000000000 +0100 @@ -70,8 +70,9 @@ } std::vector<int32> classes; - classes.reserve(fileHeader.importCount); - for(uint32 i = 0; i < fileHeader.importCount && file.CanRead(4); i++) + const uint32 importCount = std::min(fileHeader.importCount.get(), mpt::saturate_cast<uint32>(file.BytesLeft() / 4u)); + classes.reserve(importCount); + for(uint32 i = 0; i < importCount && file.CanRead(4); i++) { int32 objName = ReadUMXImportTableEntry(file, fileHeader.packageVersion); if(static_cast<size_t>(objName) < names.size()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Load_wav.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Load_wav.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Load_wav.cpp 2019-11-02 10:13:50.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Load_wav.cpp 2021-02-28 18:34:06.000000000 +0100 @@ -64,11 +64,13 @@ WAVReader wavFile(file); if(!wavFile.IsValid() - || wavFile.GetNumChannels() == 0 - || wavFile.GetNumChannels() > MAX_BASECHANNELS - || wavFile.GetBitsPerSample() == 0 - || wavFile.GetBitsPerSample() > 32 - || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat)) + || wavFile.GetNumChannels() == 0 + || wavFile.GetNumChannels() > MAX_BASECHANNELS + || wavFile.GetNumChannels() >= MAX_SAMPLES + || wavFile.GetBitsPerSample() == 0 + || wavFile.GetBitsPerSample() > 64 + || (wavFile.GetBitsPerSample() < 32 && wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat) + || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat)) { return false; } else if(loadFlags == onlyVerifyHeader) @@ -173,22 +175,22 @@ if(wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat) { - CopyWavChannel<SC::ConversionChain<SC::Convert<int16, float32>, SC::DecodeFloat32<littleEndian32> > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); + if(wavFile.GetBitsPerSample() <= 32) + CopyWavChannel<SC::ConversionChain<SC::Convert<int16, float32>, SC::DecodeFloat32<littleEndian32>>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); + else + CopyWavChannel<SC::ConversionChain<SC::Convert<int16, float64>, SC::DecodeFloat64<littleEndian64>>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); } else { if(wavFile.GetBitsPerSample() <= 8) - { CopyWavChannel<SC::DecodeUint8>(sample, sampleChunk, channel, wavFile.GetNumChannels()); - } else if(wavFile.GetBitsPerSample() <= 16) - { - CopyWavChannel<SC::DecodeInt16<0, littleEndian16> >(sample, sampleChunk, channel, wavFile.GetNumChannels()); - } else if(wavFile.GetBitsPerSample() <= 24) - { - CopyWavChannel<SC::ConversionChain<SC::Convert<int16, int32>, SC::DecodeInt24<0, littleEndian24> > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); - } else if(wavFile.GetBitsPerSample() <= 32) - { - CopyWavChannel<SC::ConversionChain<SC::Convert<int16, int32>, SC::DecodeInt32<0, littleEndian32> > >(sample, sampleChunk, channel, wavFile.GetNumChannels()); - } + else if(wavFile.GetBitsPerSample() <= 16) + CopyWavChannel<SC::DecodeInt16<0, littleEndian16>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); + else if(wavFile.GetBitsPerSample() <= 24) + CopyWavChannel<SC::ConversionChain<SC::Convert<int16, int32>, SC::DecodeInt24<0, littleEndian24>>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); + else if(wavFile.GetBitsPerSample() <= 32) + CopyWavChannel<SC::ConversionChain<SC::Convert<int16, int32>, SC::DecodeInt32<0, littleEndian32>>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); + else if(wavFile.GetBitsPerSample() <= 64) + CopyWavChannel<SC::ConversionChain<SC::Convert<int16, int64>, SC::DecodeInt64<0, littleEndian64>>>(sample, sampleChunk, channel, wavFile.GetNumChannels()); } sample.PrecomputeLoops(*this, false); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/ModSampleCopy.h new/libopenmpt-0.5.7+release.autotools/soundlib/ModSampleCopy.h --- old/libopenmpt-0.5.5+release.autotools/soundlib/ModSampleCopy.h 2019-09-06 14:51:26.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/ModSampleCopy.h 2021-02-20 15:19:02.000000000 +0100 @@ -114,12 +114,12 @@ template <typename SampleConversion, typename Tbyte> size_t CopyAndNormalizeSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, typename SampleConversion::peak_t *srcPeak = nullptr, SampleConversion conv = SampleConversion()) { - const size_t inSize = sizeof(typename SampleConversion::input_t); + const size_t sampleSize = SampleConversion::input_inc; MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); size_t numSamples = sample.nLength * sample.GetNumChannels(); - LimitMax(numSamples, sourceSize / inSize); + LimitMax(numSamples, sourceSize / sampleSize); const std::byte * inBuf = mpt::byte_cast<const std::byte*>(sourceBuffer); // Finding max value @@ -150,7 +150,7 @@ *srcPeak = sampleConv.GetSrcPeak(); } - return numSamples * inSize; + return numSamples * sampleSize; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/ModSequence.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/ModSequence.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/ModSequence.cpp 2020-10-14 19:34:25.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/ModSequence.cpp 2021-02-06 14:33:07.000000000 +0100 @@ -180,18 +180,19 @@ ORDERINDEX ModSequence::insert(ORDERINDEX pos, ORDERINDEX count, PATTERNINDEX fill) { - if (pos >= m_sndFile.GetModSpecifications().ordersMax || count == 0) + const auto ordersMax = m_sndFile.GetModSpecifications().ordersMax; + if(pos >= ordersMax || GetLengthTailTrimmed() >= ordersMax || count == 0) return 0; // Limit number of orders to be inserted so that we don't exceed the format limit. - LimitMax(count, ORDERINDEX(m_sndFile.GetModSpecifications().ordersMax - pos)); - reserve(pos + count); + LimitMax(count, static_cast<ORDERINDEX>(ordersMax - pos)); + reserve(std::max(pos, GetLength()) + count); // Inserting past the end of the container? if(pos > size()) resize(pos); std::vector<PATTERNINDEX>::insert(begin() + pos, count, fill); // Did we overgrow? Remove patterns at end. - if(size() > m_sndFile.GetModSpecifications().ordersMax) - resize(m_sndFile.GetModSpecifications().ordersMax); + if(size() > ordersMax) + resize(ordersMax); return count; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/S3MTools.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/S3MTools.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/S3MTools.cpp 2019-08-01 17:04:36.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/S3MTools.cpp 2021-02-13 20:57:13.000000000 +0100 @@ -17,7 +17,7 @@ OPENMPT_NAMESPACE_BEGIN // Convert an S3M sample header to OpenMPT's internal sample header. -void S3MSampleHeader::ConvertToMPT(ModSample &mptSmp) const +void S3MSampleHeader::ConvertToMPT(ModSample &mptSmp, bool isST3) const { mptSmp.Initialize(MOD_TYPE_S3M); mptSmp.filename = mpt::String::ReadBuf(mpt::String::maybeNullTerminated, filename); @@ -48,17 +48,18 @@ } // Volume / Panning - mptSmp.nVolume = std::min(static_cast<uint8>(defaultVolume), uint8(64)) * 4; + mptSmp.nVolume = std::min(defaultVolume.get(), uint8(64)) * 4; // C-5 frequency mptSmp.nC5Speed = c5speed; + // ST3 ignores the high 16 bits + if(isST3) + mptSmp.nC5Speed &= 0xFFFF; + if(mptSmp.nC5Speed == 0) - { mptSmp.nC5Speed = 8363; - } else if(mptSmp.nC5Speed < 1024) - { + else if(mptSmp.nC5Speed < 1024) mptSmp.nC5Speed = 1024; - } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/S3MTools.h new/libopenmpt-0.5.7+release.autotools/soundlib/S3MTools.h --- old/libopenmpt-0.5.5+release.autotools/soundlib/S3MTools.h 2020-07-15 20:07:36.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/S3MTools.h 2021-02-13 20:57:13.000000000 +0100 @@ -134,7 +134,7 @@ char magic[4]; // "SCRS" magic bytes ("SCRI" for Adlib instruments) // Convert an S3M sample header to OpenMPT's internal sample header. - void ConvertToMPT(ModSample &mptSmp) const; + void ConvertToMPT(ModSample &mptSmp, bool isST3 = false) const; // Convert OpenMPT's internal sample header to an S3M sample header. SmpLength ConvertToS3M(const ModSample &mptSmp); // Retrieve the internal sample format flags for this sample. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/SampleFormats.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/SampleFormats.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/SampleFormats.cpp 2021-01-26 23:07:05.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/SampleFormats.cpp 2021-02-28 18:34:06.000000000 +0100 @@ -422,11 +422,12 @@ WAVReader wavFile(file); if(!wavFile.IsValid() - || wavFile.GetNumChannels() == 0 - || wavFile.GetNumChannels() > 2 - || (wavFile.GetBitsPerSample() == 0 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3) - || (wavFile.GetBitsPerSample() > 64) - || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat && wavFile.GetSampleFormat() != WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtALaw && wavFile.GetSampleFormat() != WAVFormatChunk::fmtULaw)) + || wavFile.GetNumChannels() == 0 + || wavFile.GetNumChannels() > 2 + || (wavFile.GetBitsPerSample() == 0 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3) + || (wavFile.GetBitsPerSample() < 32 && wavFile.GetSampleFormat() == WAVFormatChunk::fmtFloat) + || (wavFile.GetBitsPerSample() > 64) + || (wavFile.GetSampleFormat() != WAVFormatChunk::fmtPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtFloat && wavFile.GetSampleFormat() != WAVFormatChunk::fmtIMA_ADPCM && wavFile.GetSampleFormat() != WAVFormatChunk::fmtMP3 && wavFile.GetSampleFormat() != WAVFormatChunk::fmtALaw && wavFile.GetSampleFormat() != WAVFormatChunk::fmtULaw)) { return false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/SampleIO.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/SampleIO.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/SampleIO.cpp 2020-11-19 20:59:35.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/SampleIO.cpp 2021-02-18 18:24:25.000000000 +0100 @@ -327,7 +327,7 @@ const auto &lut = GetEncoding() == uLaw ? uLawTable : aLawTable; SmpLength readLength = sample.nLength * GetNumChannels(); - LimitMax(readLength, mpt::saturate_cast<SmpLength>(file.BytesLeft())); + LimitMax(readLength, mpt::saturate_cast<SmpLength>(fileSize)); bytesRead = readLength; const uint8 *inBuf = mpt::byte_cast<const uint8*>(sourceBuf); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Snd_defs.h new/libopenmpt-0.5.7+release.autotools/soundlib/Snd_defs.h --- old/libopenmpt-0.5.5+release.autotools/soundlib/Snd_defs.h 2021-01-04 19:04:45.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Snd_defs.h 2021-03-20 14:08:00.000000000 +0100 @@ -244,26 +244,27 @@ // Module flags - contains both song configuration and playback state... Use SONG_FILE_FLAGS and SONG_PLAY_FLAGS distinguish between the two. enum SongFlags { - SONG_FASTVOLSLIDES = 0x0002, // Old Scream Tracker 3.0 volume slides - SONG_ITOLDEFFECTS = 0x0004, // Old Impulse Tracker effect implementations - SONG_ITCOMPATGXX = 0x0008, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) - SONG_LINEARSLIDES = 0x0010, // Linear slides vs. Amiga slides - SONG_PATTERNLOOP = 0x0020, // Loop current pattern (pattern editor) - SONG_STEP = 0x0040, // Song is in "step" mode (pattern editor) - SONG_PAUSED = 0x0080, // Song is paused (no tick processing, just rendering audio) - SONG_FADINGSONG = 0x0100, // Song is fading out - SONG_ENDREACHED = 0x0200, // Song is finished - SONG_FIRSTTICK = 0x1000, // Is set when the current tick is the first tick of the row - SONG_MPTFILTERMODE = 0x2000, // Local filter mode (reset filter on each note) - SONG_SURROUNDPAN = 0x4000, // Pan in the rear channels - SONG_EXFILTERRANGE = 0x8000, // Cutoff Filter has double frequency range (up to ~10Khz) - SONG_AMIGALIMITS = 0x10000, // Enforce amiga frequency limits - SONG_S3MOLDVIBRATO = 0x20000, // ScreamTracker 2 vibrato in S3M files - SONG_BREAKTOROW = 0x80000, // Break to row command encountered (internal flag, do not touch) - SONG_POSJUMP = 0x100000, // Position jump encountered (internal flag, do not touch) - SONG_PT_MODE = 0x200000, // ProTracker 1/2 playback mode - SONG_PLAYALLSONGS = 0x400000, // Play all subsongs consecutively (libopenmpt) - SONG_ISAMIGA = 0x800000, // Is an Amiga module and thus qualifies to be played using the Paula BLEP resampler + SONG_FASTVOLSLIDES = 0x02, // Old Scream Tracker 3.0 volume slides + SONG_ITOLDEFFECTS = 0x04, // Old Impulse Tracker effect implementations + SONG_ITCOMPATGXX = 0x08, // IT "Compatible Gxx" (IT's flag to behave more like other trackers w/r/t portamento effects) + SONG_LINEARSLIDES = 0x10, // Linear slides vs. Amiga slides + SONG_PATTERNLOOP = 0x20, // Loop current pattern (pattern editor) + SONG_STEP = 0x40, // Song is in "step" mode (pattern editor) + SONG_PAUSED = 0x80, // Song is paused (no tick processing, just rendering audio) + SONG_FADINGSONG = 0x0100, // Song is fading out + SONG_ENDREACHED = 0x0200, // Song is finished + SONG_FIRSTTICK = 0x1000, // Is set when the current tick is the first tick of the row + SONG_MPTFILTERMODE = 0x2000, // Local filter mode (reset filter on each note) + SONG_SURROUNDPAN = 0x4000, // Pan in the rear channels + SONG_EXFILTERRANGE = 0x8000, // Cutoff Filter has double frequency range (up to ~10Khz) + SONG_AMIGALIMITS = 0x1'0000, // Enforce amiga frequency limits + SONG_S3MOLDVIBRATO = 0x2'0000, // ScreamTracker 2 vibrato in S3M files + SONG_BREAKTOROW = 0x8'0000, // Break to row command encountered (internal flag, do not touch) + SONG_POSJUMP = 0x10'0000, // Position jump encountered (internal flag, do not touch) + SONG_PT_MODE = 0x20'0000, // ProTracker 1/2 playback mode + SONG_PLAYALLSONGS = 0x40'0000, // Play all subsongs consecutively (libopenmpt) + SONG_ISAMIGA = 0x80'0000, // Is an Amiga module and thus qualifies to be played using the Paula BLEP resampler + SONG_IMPORTED = 0x100'0000, // Song type does not represent actual module format / was imported from a different format (OpenMPT) }; DECLARE_FLAGSET(SongFlags) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Snd_fx.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Snd_fx.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Snd_fx.cpp 2021-01-02 23:31:56.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Snd_fx.cpp 2021-03-20 14:30:01.000000000 +0100 @@ -243,8 +243,6 @@ { std::vector<GetLengthType> results; GetLengthType retval; - retval.startOrder = target.startOrder; - retval.startRow = target.startRow; // Are we trying to reach a certain pattern position? const bool hasSearchTarget = target.mode != GetLengthTarget::NoTarget && target.mode != GetLengthTarget::GetAllSubsongs; @@ -259,8 +257,18 @@ // Temporary visited rows vector (so that GetLength() won't interfere with the player code if the module is playing at the same time) RowVisitor visitedRows(*this, sequence); - playState.m_nNextRow = playState.m_nRow = target.startRow; - playState.m_nNextOrder = playState.m_nCurrentOrder = target.startOrder; + // If sequence starts with some non-existent patterns, find a better start + { + ORDERINDEX startOrder = target.startOrder; + ROWINDEX startRow = target.startRow; + if(visitedRows.GetFirstUnvisitedRow(startOrder, startRow, true)) + { + target.startOrder = startOrder; + target.startRow = startRow; + } + } + retval.startRow = playState.m_nNextRow = playState.m_nRow = target.startRow; + retval.startOrder = playState.m_nNextOrder = playState.m_nCurrentOrder = target.startOrder; // Fast LUTs for commands that are too weird / complicated / whatever to emulate in sample position adjust mode. std::bitset<MAX_EFFECTS> forbiddenCommands; @@ -1317,6 +1325,7 @@ m_opl->Patch(n, chn.pModSample->adlib); m_opl->NoteCut(n); } + chn.pCurrentSample = nullptr; } #ifndef NO_PLUGINS @@ -2928,10 +2937,7 @@ { CheckNNA(nChn, instr, note, false); } - } - if(note) - { if(chn.nRestorePanOnNewNote > 0) { chn.nPan = (chn.nRestorePanOnNewNote & 0x7FFF) - 1; @@ -4699,7 +4705,14 @@ // S2x: Set FineTune case 0x20: if(!m_SongFlags[SONG_FIRSTTICK]) break; - if(GetType() != MOD_TYPE_669) + if(GetType() == MOD_TYPE_IMF) + { + if(chn.nPeriod && chn.pModSample) + { + chn.nC5Speed = Util::muldivr(chn.pModSample->nC5Speed, 1712, ProTrackerTunedPeriods[param * 12]); + chn.nPeriod = GetPeriodFromNote(chn.nNote, 0, chn.nC5Speed); + } + } else if(GetType() != MOD_TYPE_669) { chn.nC5Speed = S3MFineTuneTable[param]; chn.nFineTune = MOD2XMFineTune(param); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/Sndfile.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/Sndfile.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/Sndfile.cpp 2021-01-04 19:04:45.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/Sndfile.cpp 2021-03-20 14:11:44.000000000 +0100 @@ -455,15 +455,20 @@ m_songMessage.assign(mpt::ToCharset(mpt::Charset::Locale, unarchiver.GetComment())); } #endif +#ifdef MODPLUG_TRACKER } MPT_EXCEPTION_CATCH_OUT_OF_MEMORY(e) { MPT_EXCEPTION_DELETE_OUT_OF_MEMORY(e); + return false; +#endif // MODPLUG_TRACKER + } catch(const std::exception &) + { #ifdef MODPLUG_TRACKER return false; #else // libopenmpt already handles this. throw; -#endif // MODPLUG_TRACKER +#endif // MODPLUG_TRACKER } } else { @@ -537,9 +542,14 @@ m_nInstruments = maxInstr; // Set default play state values - if (!m_nDefaultTempo.GetInt()) m_nDefaultTempo.Set(125); - if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; - if (m_nDefaultRowsPerMeasure < m_nDefaultRowsPerBeat) m_nDefaultRowsPerMeasure = m_nDefaultRowsPerBeat; + if(!m_nDefaultTempo.GetInt()) + m_nDefaultTempo.Set(125); + else + LimitMax(m_nDefaultTempo, TEMPO(uint16_max, 0)); + if(!m_nDefaultSpeed) + m_nDefaultSpeed = 6; + if(m_nDefaultRowsPerMeasure < m_nDefaultRowsPerBeat) + m_nDefaultRowsPerMeasure = m_nDefaultRowsPerBeat; m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; @@ -956,10 +966,10 @@ m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed; m_PlayState.m_nPatternDelay = 0; m_PlayState.m_nFrameDelay = 0; - m_PlayState.m_nBufferCount = 0; m_PlayState.m_nNextPatStartRow = 0; m_SongFlags.set(SONG_PATTERNLOOP); } + m_PlayState.m_nBufferCount = 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/UMXTools.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/UMXTools.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/UMXTools.cpp 2018-06-10 01:17:45.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/UMXTools.cpp 2021-03-16 00:20:11.000000000 +0100 @@ -146,7 +146,7 @@ { return ""; } - name.reserve(length); + name.reserve(std::min(length, mpt::saturate_cast<int32>(chunk.BytesLeft()))); } // Simple zero-terminated string @@ -174,8 +174,9 @@ { return names; } - names.reserve(fileHeader.nameCount); - for(uint32 i = 0; i < fileHeader.nameCount && file.CanRead(4); i++) + const uint32 nameCount = std::min(fileHeader.nameCount.get(), mpt::saturate_cast<uint32>(file.BytesLeft() / 5u)); + names.reserve(nameCount); + for(uint32 i = 0; i < nameCount && file.CanRead(5); i++) { names.push_back(ReadUMXNameTableEntry(file, fileHeader.packageVersion)); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/modsmp_ctrl.cpp new/libopenmpt-0.5.7+release.autotools/soundlib/modsmp_ctrl.cpp --- old/libopenmpt-0.5.5+release.autotools/soundlib/modsmp_ctrl.cpp 2021-01-04 18:35:23.000000000 +0100 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/modsmp_ctrl.cpp 2021-03-14 16:03:23.000000000 +0100 @@ -240,7 +240,70 @@ template <class T> -static void ConvertMonoToStereoImpl(const T * MPT_RESTRICT src, T * MPT_RESTRICT dst, SmpLength length) +static void SplitStereoImpl(void *destL, void *destR, const T *source, SmpLength length) +{ + T *l = static_cast<T *>(destL), *r = static_cast<T*>(destR); + while(length--) + { + *(l++) = source[0]; + *(r++) = source[1]; + source += 2; + } +} + + +// Converts a stereo sample into two mono samples. Source sample will not be deleted. +bool SplitStereo(const ModSample &source, ModSample &left, ModSample &right, CSoundFile &sndFile) +{ + if(!source.HasSampleData() || source.GetNumChannels() != 2 || &left == &right) + return false; + const bool sourceIsLeft = &left == &source, sourceIsRight = &right == &source; + if(left.HasSampleData() && !sourceIsLeft) + return false; + if(right.HasSampleData() && !sourceIsRight) + return false; + + void *leftData = sourceIsLeft ? left.samplev() : ModSample::AllocateSample(source.nLength, source.GetElementarySampleSize()); + void *rightData = sourceIsRight ? right.samplev() : ModSample::AllocateSample(source.nLength, source.GetElementarySampleSize()); + if(!leftData || !rightData) + { + if(!sourceIsLeft) + ModSample::FreeSample(leftData); + if(!sourceIsRight) + ModSample::FreeSample(rightData); + return false; + } + + if(source.GetElementarySampleSize() == 2) + SplitStereoImpl(leftData, rightData, source.sample16(), source.nLength); + else if(source.GetElementarySampleSize() == 1) + SplitStereoImpl(leftData, rightData, source.sample8(), source.nLength); + else + MPT_ASSERT_NOTREACHED(); + + CriticalSection cs; + left = source; + left.uFlags.reset(CHN_STEREO); + left.pData.pSample = leftData; + + right = source; + right.uFlags.reset(CHN_STEREO); + right.pData.pSample = rightData; + + for(auto &chn : sndFile.m_PlayState.Chn) + { + if(chn.pModSample == &left || chn.pModSample == &right) + chn.dwFlags.reset(CHN_STEREO); + } + + left.PrecomputeLoops(sndFile, false); + right.PrecomputeLoops(sndFile, false); + return true; +} + + +template <class T> +static void ConvertMonoToStereoImpl(const T *MPT_RESTRICT src, T *MPT_RESTRICT dst, SmpLength length) { while(length--) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.5+release.autotools/soundlib/modsmp_ctrl.h new/libopenmpt-0.5.7+release.autotools/soundlib/modsmp_ctrl.h --- old/libopenmpt-0.5.5+release.autotools/soundlib/modsmp_ctrl.h 2019-07-16 22:39:22.000000000 +0200 +++ new/libopenmpt-0.5.7+release.autotools/soundlib/modsmp_ctrl.h 2021-03-14 16:03:23.000000000 +0100 @@ -46,6 +46,10 @@ // Convert a sample with any number of channels to mono bool ConvertToMono(ModSample &smp, CSoundFile &sndFile, StereoToMonoMode conversionMode); +// Converts a stereo sample into two mono samples. Source sample will not be deleted. +// Either of the two target samples may be identical to the source sample. +bool SplitStereo(const ModSample &source, ModSample &left, ModSample &right, CSoundFile &sndFile); + // Convert a mono sample to stereo bool ConvertToStereo(ModSample &smp, CSoundFile &sndFile);
