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-08-26 23:14:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libopenmpt (Old) and /work/SRC/openSUSE:Factory/.libopenmpt.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libopenmpt" Thu Aug 26 23:14:13 2021 rev:30 rq:913906 version:0.5.11 Changes: -------- --- /work/SRC/openSUSE:Factory/libopenmpt/libopenmpt.changes 2021-07-13 22:37:01.786324438 +0200 +++ /work/SRC/openSUSE:Factory/.libopenmpt.new.1899/libopenmpt.changes 2021-08-26 23:14:20.792271616 +0200 @@ -1,0 +2,19 @@ +Mon Aug 23 22:18:43 UTC 2021 - Mia Herkt <m...@0x0.st> + +- Update to 0.5.11: + * [Sec] Possible crash with malformed modules when trying to + access non-existent plugin slots FX251-FX255. + * [Sec] Possible read beyond sample start after swapping to a + sample with loop points set but not loop enabled. + * [Sec] Fixed various possible crashes with malformed MMCMP + files. + * [Sec] MED: Possible read past end of sequence name + (stack-allocated, so relatively unlikely to result in a + crash). + * Fixed excessive memory usage with files claiming to have an + extremely high rows per beat count while also using tempo + swing. Maximum rows per beat are now limited to 65536. + * STP: Avoid creating thousands of patterns when loading + malformed files even though no more pattern data can be read. + +------------------------------------------------------------------- Old: ---- libopenmpt-0.5.10+release.autotools.tar.gz New: ---- libopenmpt-0.5.11+release.autotools.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libopenmpt.spec ++++++ --- /var/tmp/diff_new_pack.OIxrGM/_old 2021-08-26 23:14:21.372271102 +0200 +++ /var/tmp/diff_new_pack.OIxrGM/_new 2021-08-26 23:14:21.376271098 +0200 @@ -21,7 +21,7 @@ %define libopenmpt_modplug_version 0.8.9.0 Name: libopenmpt -Version: 0.5.10 +Version: 0.5.11 Release: 0 Summary: C++ and C library to decode tracker music files License: BSD-3-Clause ++++++ libopenmpt-0.5.10+release.autotools.tar.gz -> libopenmpt-0.5.11+release.autotools.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/common/versionNumber.h new/libopenmpt-0.5.11+release.autotools/common/versionNumber.h --- old/libopenmpt-0.5.10+release.autotools/common/versionNumber.h 2021-07-04 18:10:39.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/common/versionNumber.h 2021-08-22 14:54:32.000000000 +0200 @@ -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 11 +#define VER_MINOR 12 #define VER_MINORMINOR 00 OPENMPT_NAMESPACE_END diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/configure new/libopenmpt-0.5.11+release.autotools/configure --- old/libopenmpt-0.5.10+release.autotools/configure 2021-07-04 18:34:27.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/configure 2021-08-22 15:24:59.000000000 +0200 @@ -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.10+release.autotools. +# Generated by GNU Autoconf 2.69 for libopenmpt 0.5.11+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.10+release.autotools' -PACKAGE_STRING='libopenmpt 0.5.10+release.autotools' +PACKAGE_VERSION='0.5.11+release.autotools' +PACKAGE_STRING='libopenmpt 0.5.11+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.10+release.autotools to adapt to many kinds of systems. +\`configure' configures libopenmpt 0.5.11+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.10+release.autotools:";; + short | recursive ) echo "Configuration of libopenmpt 0.5.11+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.10+release.autotools +libopenmpt configure 0.5.11+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.10+release.autotools, which was +It was created by libopenmpt $as_me 0.5.11+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.10+release.autotools' + VERSION='0.5.11+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.10\"" >>confdefs.h +$as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.11\"" >>confdefs.h -$as_echo "#define MPT_SVNVERSION \"15412\"" >>confdefs.h +$as_echo "#define MPT_SVNVERSION \"15552\"" >>confdefs.h -$as_echo "#define MPT_SVNDATE \"2021-07-04T16:30:04.479627Z\"" >>confdefs.h +$as_echo "#define MPT_SVNDATE \"2021-08-22T13:20:52.381159Z\"" >>confdefs.h $as_echo "#define MPT_PACKAGE true" >>confdefs.h @@ -22524,7 +22524,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.10+release.autotools, which was +This file was extended by libopenmpt $as_me 0.5.11+release.autotools, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22591,7 +22591,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.10+release.autotools +libopenmpt config.status 0.5.11+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.10+release.autotools/configure.ac new/libopenmpt-0.5.11+release.autotools/configure.ac --- old/libopenmpt-0.5.10+release.autotools/configure.ac 2021-07-04 18:34:11.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/configure.ac 2021-08-22 15:24:50.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([libopenmpt], [0.5.10+release.autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/]) +AC_INIT([libopenmpt], [0.5.11+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.10"], [svn version]) -AC_DEFINE([MPT_SVNVERSION], ["15412"], [svn version]) -AC_DEFINE([MPT_SVNDATE], ["2021-07-04T16:30:04.479627Z"], [svn date]) +AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/tags/libopenmpt-0.5.11"], [svn version]) +AC_DEFINE([MPT_SVNVERSION], ["15552"], [svn version]) +AC_DEFINE([MPT_SVNDATE], ["2021-08-22T13:20:52.381159Z"], [svn date]) AC_DEFINE([MPT_PACKAGE], [true], [is package]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/libopenmpt/dox/changelog.md new/libopenmpt-0.5.11+release.autotools/libopenmpt/dox/changelog.md --- old/libopenmpt-0.5.10+release.autotools/libopenmpt/dox/changelog.md 2021-07-04 18:30:02.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/libopenmpt/dox/changelog.md 2021-08-22 15:20:49.000000000 +0200 @@ -5,6 +5,27 @@ For fully detailed change log, please see the source repository directly. This is just a high-level summary. +### libopenmpt 0.5.11 (2021-08-22) + + * [**Sec**] Possible crash with malformed modules when trying to access + non-existent plugin slots FX251-FX255. (r15479, r15518) + * [**Sec**] Possible read beyond sample start after swapping to a sample with + loop points set but not loop enabled. (r15499) + * [**Sec**] Fixed various possible crashes with malformed MMCMP files. + (r15504, 15528) + * [**Sec**] MED: Possible read past end of sequence name (stack-allocated, so + relatively unlikely to result in a crash). (r15477) + + * Fixed excessive memory usage with files claiming to have an extremely high + rows per beat count while also using tempo swing. Maximum rows per beat are + now limited to 65536. + * STP: Avoid creating thousands of patterns when loading malformed files even + though no more pattern data can be read. + + * mpg123: Update to v1.28.2 (2021-07-12). + * stb_vorbis: Update v1.22 commit 5a0bb8b1c1b1ca3f4e2485f4114c1c8ea021b781 + (2021-07-12). + ### libopenmpt 0.5.10 (2021-07-04) * S3M: Honor the Stereo flag not being set. This improves the sound of some diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/libopenmpt/libopenmpt_version.h new/libopenmpt-0.5.11+release.autotools/libopenmpt/libopenmpt_version.h --- old/libopenmpt-0.5.10+release.autotools/libopenmpt/libopenmpt_version.h 2021-07-04 18:30:02.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/libopenmpt/libopenmpt_version.h 2021-08-22 15:20:49.000000000 +0200 @@ -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 10 +#define OPENMPT_API_VERSION_PATCH 11 /*! \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.10+release.autotools/libopenmpt/libopenmpt_version.mk new/libopenmpt-0.5.11+release.autotools/libopenmpt/libopenmpt_version.mk --- old/libopenmpt-0.5.10+release.autotools/libopenmpt/libopenmpt_version.mk 2021-07-04 18:30:02.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/libopenmpt/libopenmpt_version.mk 2021-08-22 15:20:49.000000000 +0200 @@ -1,8 +1,8 @@ LIBOPENMPT_VERSION_MAJOR=0 LIBOPENMPT_VERSION_MINOR=5 -LIBOPENMPT_VERSION_PATCH=10 +LIBOPENMPT_VERSION_PATCH=11 LIBOPENMPT_VERSION_PREREL= LIBOPENMPT_LTVER_CURRENT=2 -LIBOPENMPT_LTVER_REVISION=10 +LIBOPENMPT_LTVER_REVISION=11 LIBOPENMPT_LTVER_AGE=2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/man/openmpt123.1 new/libopenmpt-0.5.11+release.autotools/man/openmpt123.1 --- old/libopenmpt-0.5.10+release.autotools/man/openmpt123.1 2021-07-04 18:34:11.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/man/openmpt123.1 2021-08-22 15:24:49.000000000 +0200 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.8. -.TH OPENMPT123 "1" "July 2021" "openmpt123 v0.5.10" "User Commands" +.TH OPENMPT123 "1" "August 2021" "openmpt123 v0.5.11" "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.10+release.autotools/soundlib/ContainerMMCMP.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/ContainerMMCMP.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/ContainerMMCMP.cpp 2019-12-24 10:29:44.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/ContainerMMCMP.cpp 2021-08-14 00:30:36.000000000 +0200 @@ -102,6 +102,7 @@ if(pos >= unpackedData.size()) return false; if(len > unpackedData.size()) return false; if(len > unpackedData.size() - pos) return false; + if(!len) return false; return true; } @@ -252,7 +253,9 @@ if(!psubblk) return false; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; char *pDest = &(unpackedData[psubblk[subblk].unpk_pos]); - uint32 dwSize = psubblk[subblk].unpk_size; + uint32 dwSize = psubblk[subblk].unpk_size & ~1u; + if(!dwSize) + return false; uint32 dwPos = 0; uint32 numbits = blk.num_bits; uint32 oldval = 0; @@ -316,7 +319,9 @@ dwPos = 0; if(!(subblk < blk.sub_blk)) break; if(!MMCMP_IsDstBlockValid(unpackedData, psubblk[subblk])) return false; - dwSize = psubblk[subblk].unpk_size; + dwSize = psubblk[subblk].unpk_size & ~1u; + if(!dwSize) + return false; pDest = &(unpackedData[psubblk[subblk].unpk_pos]); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Dlsbank.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Dlsbank.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Dlsbank.cpp 2021-05-16 18:09:21.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Dlsbank.cpp 2021-08-15 20:42:21.000000000 +0200 @@ -581,45 +581,52 @@ const DLSINSTRUMENT *CDLSBank::FindInstrument(bool isDrum, uint32 bank, uint32 program, uint32 key, uint32 *pInsNo) const { - if (m_Instruments.empty()) return nullptr; - for (uint32 iIns=0; iIns<m_Instruments.size(); iIns++) + if(m_Instruments.empty()) + return nullptr; + uint8 smallestRegion = uint8_max; + uint32 bestMatch = uint32_max; + for (uint32 iIns = 0; iIns < m_Instruments.size(); iIns++) { const DLSINSTRUMENT &dlsIns = m_Instruments[iIns]; uint32 insbank = ((dlsIns.ulBank & 0x7F00) >> 1) | (dlsIns.ulBank & 0x7F); - if ((bank >= 0x4000) || (insbank == bank)) + if((bank >= 0x4000) || (insbank == bank)) { - if (isDrum) + if(isDrum && (dlsIns.ulBank & F_INSTRUMENT_DRUMS)) { - if (dlsIns.ulBank & F_INSTRUMENT_DRUMS) + if((program >= 0x80) || (program == (dlsIns.ulInstrument & 0x7F))) { - if ((program >= 0x80) || (program == (dlsIns.ulInstrument & 0x7F))) + for(const auto ®ion : dlsIns.Regions) { - for (uint32 iRgn=0; iRgn<dlsIns.nRegions; iRgn++) + if(region.nWaveLink == Util::MaxValueOfType(region.nWaveLink)) + continue; + const uint8 regionSize = region.uKeyMax - region.uKeyMin; + if(regionSize > smallestRegion) + continue; + + if((!key) || (key >= 0x80) + || ((key >= region.uKeyMin) + && (key <= region.uKeyMax))) { - if ((!key) || (key >= 0x80) - || ((key >= dlsIns.Regions[iRgn].uKeyMin) - && (key <= dlsIns.Regions[iRgn].uKeyMax))) - { - if (pInsNo) *pInsNo = iIns; - return &dlsIns; - } + smallestRegion = regionSize; + bestMatch = iIns; } } } - } else + } else if(!isDrum && !(dlsIns.ulBank & F_INSTRUMENT_DRUMS)) { - if (!(dlsIns.ulBank & F_INSTRUMENT_DRUMS)) + if((program >= 0x80) || (program == (dlsIns.ulInstrument & 0x7F))) { - if ((program >= 0x80) || (program == (dlsIns.ulInstrument & 0x7F))) - { - if (pInsNo) *pInsNo = iIns; - return &dlsIns; - } + if(pInsNo) + *pInsNo = iIns; + return &dlsIns; } } } } - return nullptr; + + if(pInsNo && bestMatch != uint32_max) + *pInsNo = bestMatch; + return bestMatch != uint32_max ? &m_Instruments[bestMatch] : nullptr; } @@ -678,7 +685,7 @@ { case IFFID_rgn: // Level 1 region case IFFID_rgn2: // Level 2 region - if (pDlsIns->nRegions < DLSMAXREGIONS) pDlsIns->nRegions++; + pDlsIns->Regions.push_back({}); break; } } else @@ -696,11 +703,11 @@ } case IFFID_rgnh: - if (pDlsIns->nRegions < DLSMAXREGIONS) + if(!pDlsIns->Regions.empty()) { RGNHChunk rgnh; chunk.ReadStruct(rgnh); - DLSREGION ®ion = pDlsIns->Regions[pDlsIns->nRegions]; + DLSREGION ®ion = pDlsIns->Regions.back(); region.uKeyMin = (uint8)rgnh.RangeKey.usLow; region.uKeyMax = (uint8)rgnh.RangeKey.usHigh; region.fuOptions = (uint8)(rgnh.usKeyGroup & DLSREGION_KEYGROUPMASK); @@ -712,11 +719,11 @@ break; case IFFID_wlnk: - if (pDlsIns->nRegions < DLSMAXREGIONS) + if (!pDlsIns->Regions.empty()) { WLNKChunk wlnk; chunk.ReadStruct(wlnk); - DLSREGION ®ion = pDlsIns->Regions[pDlsIns->nRegions]; + DLSREGION ®ion = pDlsIns->Regions.back(); region.nWaveLink = (uint16)wlnk.ulTableIndex; if((region.nWaveLink < Util::MaxValueOfType(region.nWaveLink)) && (region.nWaveLink >= m_nMaxWaveLink)) m_nMaxWaveLink = region.nWaveLink + 1; @@ -726,9 +733,9 @@ break; case IFFID_wsmp: - if (pDlsIns->nRegions < DLSMAXREGIONS) + if(!pDlsIns->Regions.empty()) { - DLSREGION ®ion = pDlsIns->Regions[pDlsIns->nRegions]; + DLSREGION ®ion = pDlsIns->Regions.back(); WSMPCHUNK wsmp; chunk.ReadStruct(wsmp); region.fuOptions |= DLSREGION_OVERRIDEWSMP; @@ -762,10 +769,7 @@ { ART1Chunk art1; chunk.ReadStruct(art1); - if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) - { - if (pDlsIns->nRegions >= DLSMAXREGIONS) break; - } else + if(!(pDlsIns->ulBank & F_INSTRUMENT_DRUMS)) { pDlsIns->nMelodicEnv = static_cast<uint32>(m_Envelopes.size() + 1); } @@ -1083,7 +1087,7 @@ dlsIns.nMelodicEnv = static_cast<uint32>(m_Envelopes.size()); } // Load Instrument Bags - dlsIns.nRegions = 0; + dlsIns.Regions.clear(); for(const auto nInstrNdx : instruments) { if(nInstrNdx >= numInsts) @@ -1091,13 +1095,13 @@ sf2info.insts.Seek(nInstrNdx * sizeof(SFINST)); SFINST insts[2]; sf2info.insts.ReadArray(insts); - const auto startRegion = dlsIns.nRegions; - dlsIns.nRegions += insts[1].wInstBagNdx - insts[0].wInstBagNdx; + const auto startRegion = static_cast<uint32>(dlsIns.Regions.size()); + const auto endRegion = startRegion + insts[1].wInstBagNdx - insts[0].wInstBagNdx; + dlsIns.Regions.resize(endRegion); //Log("\nIns %3d, %2d regions:\n", nIns, pSmp->nRegions); - if (dlsIns.nRegions > DLSMAXREGIONS) dlsIns.nRegions = DLSMAXREGIONS; DLSREGION *pRgn = &dlsIns.Regions[startRegion]; bool hasGlobalZone = false; - for(uint32 nRgn = startRegion; nRgn < dlsIns.nRegions; nRgn++, pRgn++) + for(uint32 nRgn = startRegion; nRgn < endRegion; nRgn++, pRgn++) { uint32 ibagcnt = insts[0].wInstBagNdx + nRgn - startRegion; if(ibagcnt >= numInstBags) @@ -1488,16 +1492,22 @@ uint32 CDLSBank::GetRegionFromKey(uint32 nIns, uint32 nKey) const { - if (nIns >= m_Instruments.size()) return 0; + if(nIns >= m_Instruments.size()) + return 0; const DLSINSTRUMENT &dlsIns = m_Instruments[nIns]; - for (uint32 rgn = 0; rgn < dlsIns.nRegions; rgn++) - { - if ((nKey >= dlsIns.Regions[rgn].uKeyMin) && (nKey <= dlsIns.Regions[rgn].uKeyMax)) - { - return rgn; - } + uint8 smallestRegion = uint8_max; + uint32 region = 0; + for(uint32 rgn = 0; rgn < static_cast<uint32>(dlsIns.Regions.size()); rgn++) + { + if(nKey < dlsIns.Regions[rgn].uKeyMin || nKey > dlsIns.Regions[rgn].uKeyMax) + continue; + const uint8 regionSize = dlsIns.Regions[rgn].uKeyMax - dlsIns.Regions[rgn].uKeyMin; + if(regionSize > smallestRegion) + continue; + region = rgn; + smallestRegion = regionSize; } - return 0; + return region; } @@ -1514,7 +1524,7 @@ return false; } const DLSINSTRUMENT &dlsIns = m_Instruments[nIns]; - if (nRgn >= dlsIns.nRegions) + if(nRgn >= dlsIns.Regions.size()) { #ifdef DLSBANK_LOG MPT_LOG(LogDebug, "DLSBANK", mpt::format(U_("invalid waveform region: nIns=%1 nRgn=%2 pSmp->nRegions=%3"))(nIns, nRgn, dlsIns.nRegions)); @@ -1535,6 +1545,7 @@ { return false; } + mpt::IO::Offset sampleOffset = mpt::saturate_cast<mpt::IO::Offset>(m_WaveForms[nWaveLink] + m_dwWavePoolOffset); if(mpt::IO::SeekAbsolute(f, sampleOffset)) { @@ -1586,11 +1597,15 @@ uint32 dwLen = 0; bool ok, hasWaveform; - if (nIns >= m_Instruments.size()) return false; + if(nIns >= m_Instruments.size()) + return false; const DLSINSTRUMENT *pDlsIns = &m_Instruments[nIns]; - if (nRgn >= pDlsIns->nRegions) return false; - if (!ExtractWaveForm(nIns, nRgn, pWaveForm, dwLen)) return false; - if (dwLen < 16) return false; + if(nRgn >= pDlsIns->Regions.size()) + return false; + if(!ExtractWaveForm(nIns, nRgn, pWaveForm, dwLen)) + return false; + if(dwLen < 16) + return false; ok = false; FileReader wsmpChunk; @@ -1719,22 +1734,24 @@ bool CDLSBank::ExtractInstrument(CSoundFile &sndFile, INSTRUMENTINDEX nInstr, uint32 nIns, uint32 nDrumRgn) const { - SAMPLEINDEX RgnToSmp[DLSMAXREGIONS]; uint32 nRgnMin, nRgnMax, nEnv; if (nIns >= m_Instruments.size()) return false; const DLSINSTRUMENT *pDlsIns = &m_Instruments[nIns]; + std::vector<SAMPLEINDEX> RgnToSmp(pDlsIns->Regions.size()); if (pDlsIns->ulBank & F_INSTRUMENT_DRUMS) { - if (nDrumRgn >= pDlsIns->nRegions) return false; + if(nDrumRgn >= pDlsIns->Regions.size()) + return false; nRgnMin = nDrumRgn; nRgnMax = nDrumRgn+1; nEnv = pDlsIns->Regions[nDrumRgn].uPercEnv; } else { - if (!pDlsIns->nRegions) return false; + if(pDlsIns->Regions.empty()) + return false; nRgnMin = 0; - nRgnMax = pDlsIns->nRegions; + nRgnMax = static_cast<uint32>(pDlsIns->Regions.size()); nEnv = pDlsIns->nMelodicEnv; } if(nRgnMin == 0 && (pDlsIns->Regions[0].fuOptions & DLSREGION_ISGLOBAL)) @@ -1742,8 +1759,8 @@ #ifdef DLSINSTR_LOG MPT_LOG(LogDebug, "DLSINSTR", mpt::format(U_("DLS Instrument #%1: %2"))(nIns, mpt::ToUnicode(mpt::Charset::ASCII, mpt::String::ReadAutoBuf(pDlsIns->szName)))); MPT_LOG(LogDebug, "DLSINSTR", mpt::format(U_(" Bank=0x%1 Instrument=0x%2"))(mpt::ufmt::HEX0<4>(pDlsIns->ulBank), mpt::ufmt::HEX0<4>(pDlsIns->ulInstrument))); - MPT_LOG(LogDebug, "DLSINSTR", mpt::format(U_(" %1 regions, nMelodicEnv=%2"))(pDlsIns->nRegions, pDlsIns->nMelodicEnv)); - for (uint32 iDbg=0; iDbg<pDlsIns->nRegions; iDbg++) + MPT_LOG(LogDebug, "DLSINSTR", mpt::format(U_(" %1 regions, nMelodicEnv=%2"))(pDlsIns->Regions.size(), pDlsIns->nMelodicEnv)); + for (uint32 iDbg=0; iDbg<pDlsIns->Regions.size(); iDbg++) { const DLSREGION *prgn = &pDlsIns->Regions[iDbg]; MPT_LOG(LogDebug, "DLSINSTR", mpt::format(U_(" Region %1:"))(iDbg)); @@ -2036,9 +2053,11 @@ const char *CDLSBank::GetRegionName(uint32 nIns, uint32 nRgn) const { - if (nIns >= m_Instruments.size()) return nullptr; + if(nIns >= m_Instruments.size()) + return nullptr; const DLSINSTRUMENT &dlsIns = m_Instruments[nIns]; - if (nRgn >= dlsIns.nRegions) return nullptr; + if(nRgn >= dlsIns.Regions.size()) + return nullptr; if (m_nType & SOUNDBANK_TYPE_SF2) { @@ -2055,7 +2074,7 @@ uint8 CDLSBank::GetPanning(uint32 ins, uint32 region) const { const DLSINSTRUMENT &dlsIns = m_Instruments[ins]; - if(region >= CountOf(dlsIns.Regions)) + if(region >= dlsIns.Regions.size()) return 128; const DLSREGION &rgn = dlsIns.Regions[region]; if(dlsIns.ulBank & F_INSTRUMENT_DRUMS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Dlsbank.h new/libopenmpt-0.5.11+release.autotools/soundlib/Dlsbank.h --- old/libopenmpt-0.5.10+release.autotools/soundlib/Dlsbank.h 2020-05-27 23:03:13.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Dlsbank.h 2021-08-01 19:32:27.000000000 +0200 @@ -23,8 +23,6 @@ #ifdef MODPLUG_TRACKER -#define DLSMAXREGIONS 128 - struct DLSREGION { uint32 ulLoopStart; @@ -55,12 +53,12 @@ struct DLSINSTRUMENT { - uint32 ulBank, ulInstrument; - uint32 nRegions, nMelodicEnv; - DLSREGION Regions[DLSMAXREGIONS]; + uint32 ulBank = 0, ulInstrument = 0; + uint32 nMelodicEnv = 0; + std::vector<DLSREGION> Regions; char szName[32]; // SF2 stuff (DO NOT USE! -> used internally by the SF2 loader) - uint16 wPresetBagNdx, wPresetBagNum; + uint16 wPresetBagNdx = 0, wPresetBagNum = 0; }; struct DLSSAMPLEEX diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Fastmix.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Fastmix.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Fastmix.cpp 2021-05-05 18:54:53.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Fastmix.cpp 2021-08-02 19:16:29.000000000 +0200 @@ -248,7 +248,7 @@ { if (nPosDest < nLoopStart) { - nSmpCount = DistanceToBufferLength(SamplePosition(chn.nLoopStart, 0), nPos, nInv); + nSmpCount = DistanceToBufferLength(SamplePosition(nLoopStart, 0), nPos, nInv); } } else { @@ -605,7 +605,7 @@ if (!plugin.IsOutputToMaster()) { PLUGINDEX nOutput = plugin.GetOutputPlugin(); - if(nOutput > plug && nOutput != PLUGINDEX_INVALID + if(nOutput > plug && nOutput < MAX_MIXPLUGINS && m_MixPlugins[nOutput].pMixPlugin != nullptr) { IMixPlugin *outPlugin = m_MixPlugins[nOutput].pMixPlugin; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/InstrumentExtensions.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/InstrumentExtensions.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/InstrumentExtensions.cpp 2020-03-13 21:38:27.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/InstrumentExtensions.cpp 2021-08-02 08:45:07.000000000 +0200 @@ -596,7 +596,7 @@ case MagicBE("R..."): { // Resampling has been written as various sizes including uint16 and uint32 in the past - uint32 tmp = file.ReadTruncatedIntLE<uint32>(fsize); + uint32 tmp = file.ReadSizedIntLE<uint32>(fsize); if(Resampling::IsKnownMode(tmp)) input->resampling = static_cast<ResamplingMode>(tmp); result = true; @@ -604,27 +604,27 @@ case MagicBE("PTTL"): { // Integer part of pitch/tempo lock - uint16 tmp = file.ReadTruncatedIntLE<uint16>(fsize); + uint16 tmp = file.ReadSizedIntLE<uint16>(fsize); input->pitchToTempoLock.Set(tmp, input->pitchToTempoLock.GetFract()); result = true; } break; case MagicLE("PTTF"): { // Fractional part of pitch/tempo lock - uint16 tmp = file.ReadTruncatedIntLE<uint16>(fsize); + uint16 tmp = file.ReadSizedIntLE<uint16>(fsize); input->pitchToTempoLock.Set(input->pitchToTempoLock.GetInt(), tmp); result = true; } break; case MagicBE("VE.."): - input->VolEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadTruncatedIntLE<uint32>(fsize))); + input->VolEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadSizedIntLE<uint32>(fsize))); result = true; break; case MagicBE("PE.."): - input->PanEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadTruncatedIntLE<uint32>(fsize))); + input->PanEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadSizedIntLE<uint32>(fsize))); result = true; break; case MagicBE("PiE."): - input->PitchEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadTruncatedIntLE<uint32>(fsize))); + input->PitchEnv.resize(std::min(uint32(MAX_ENVPOINTS), file.ReadSizedIntLE<uint32>(fsize))); result = true; break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Load_it.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Load_it.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Load_it.cpp 2021-05-13 15:40:40.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Load_it.cpp 2021-08-01 16:20:49.000000000 +0200 @@ -2448,8 +2448,10 @@ // Validate read values. Limit(m_nDefaultTempo, GetModSpecifications().GetTempoMin(), GetModSpecifications().GetTempoMax()); - if(m_nTempoMode >= tempoModeMax) m_nTempoMode = tempoModeClassic; - if(m_nMixLevels >= mixLevelsMax) m_nMixLevels = mixLevelsOriginal; + if(m_nTempoMode >= tempoModeMax) + m_nTempoMode = tempoModeClassic; + if(m_nMixLevels >= mixLevelsMax) + m_nMixLevels = mixLevelsOriginal; //m_dwCreatedWithVersion //m_dwLastSavedWithVersion //m_nSamplePreAmp @@ -2458,7 +2460,8 @@ LimitMax(m_nDefaultGlobalVolume, MAX_GLOBAL_VOLUME); //m_nRestartPos //m_ModFlags - if(!m_tempoSwing.empty()) m_tempoSwing.resize(m_nDefaultRowsPerBeat); + LimitMax(m_nDefaultRowsPerBeat, MAX_ROWS_PER_BEAT); + LimitMax(m_nDefaultRowsPerMeasure, MAX_ROWS_PER_BEAT); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Load_med.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Load_med.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Load_med.cpp 2020-11-10 19:20:55.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Load_med.cpp 2021-08-01 21:00:31.000000000 +0200 @@ -1139,7 +1139,7 @@ } } if(playSeq.name[0]) - order.SetName(mpt::ToUnicode(mpt::Charset::ISO8859_1, playSeq.name)); + order.SetName(mpt::ToUnicode(mpt::Charset::ISO8859_1, mpt::String::ReadAutoBuf(playSeq.name))); // Play commands (jump / stop) if(playSeq.commandTableOffset > 0 && file.Seek(playSeq.commandTableOffset)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Load_mid.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Load_mid.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Load_mid.cpp 2020-11-24 19:24:05.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Load_mid.cpp 2021-08-16 21:46:15.000000000 +0200 @@ -697,14 +697,26 @@ uint16 finishedTracks = 0; PATTERNINDEX emptyPattern = PATTERNINDEX_INVALID; - ORDERINDEX lastOrd = 0; - ROWINDEX lastRow = 0; + ORDERINDEX lastOrd = 0, loopEndOrd = ORDERINDEX_INVALID; + ROWINDEX lastRow = 0, loopEndRow = ROWINDEX_INVALID; ROWINDEX restartRow = ROWINDEX_INVALID; int8 masterTranspose = 0; bool isXG = false; bool isEMIDI = false; + bool isEMIDILoop = false; const bool isType2 = (fileHeader.format == 2); + const auto ModPositionFromTick = [&](const tick_t tick, const tick_t offset = 0) + { + tick_t modTicks = Util::muldivr_unsigned(tick, quantize * ticksPerRow, ppqn * 4u) - offset; + + ORDERINDEX ord = static_cast<ORDERINDEX>((modTicks / ticksPerRow) / patternLen); + ROWINDEX row = (modTicks / ticksPerRow) % patternLen; + uint8 delay = static_cast<uint8>(modTicks % ticksPerRow); + + return std::make_tuple(ord, row, delay); + }; + while(finishedTracks < numTracks) { uint16 t = 0; @@ -721,11 +733,7 @@ } FileReader &track = tracks[t].track; - tick_t modTicks = Util::muldivr_unsigned(tick, quantize * ticksPerRow, ppqn * 4u); - - ORDERINDEX ord = static_cast<ORDERINDEX>((modTicks / ticksPerRow) / patternLen); - ROWINDEX row = (modTicks / ticksPerRow) % patternLen; - uint8 delay = static_cast<uint8>(modTicks % ticksPerRow); + const auto [ord, row, delay] = ModPositionFromTick(tick); if(ord >= Order().GetLength()) { @@ -800,6 +808,9 @@ { Order().SetRestartPos(ord); restartRow = row; + } else if(!mpt::CompareNoCaseAscii(s, "loopEnd")) + { + std::tie(loopEndOrd, loopEndRow, std::ignore) = ModPositionFromTick(tick, 1); } } break; @@ -1003,13 +1014,31 @@ case 111: // Non-standard MIDI loop point. May conflict with Apogee EMIDI CCs (110/111), which is why we also check if CC 110 is ever used. - if(data2 == 0) + if(data2 == 0 && !isEMIDI) { Order().SetRestartPos(ord); restartRow = row; } break; + case 118: + // EMIDI Global Loop Start + isEMIDI = true; + isEMIDILoop = false; + Order().SetRestartPos(ord); + restartRow = row; + break; + + case 119: + // EMIDI Global Loop End + if(data2 == 0x7F) + { + isEMIDILoop = true; + isEMIDI = true; + std::tie(loopEndOrd, loopEndRow, std::ignore) = ModPositionFromTick(tick, 1); + } + break; + case MIDIEvents::MIDICC_AllControllersOff: midiChnStatus[midiCh].ResetAllControllers(); break; @@ -1210,18 +1239,29 @@ } } + if(isEMIDILoop) + isEMIDI = false; + if(isEMIDI) { Order().SetRestartPos(0); } - if(Order().IsValidPat(lastOrd)) + if(loopEndOrd == ORDERINDEX_INVALID) + loopEndOrd = lastOrd; + if(loopEndRow == ROWINDEX_INVALID) + loopEndRow = lastRow; + + if(Order().IsValidPat(loopEndOrd)) { - PATTERNINDEX lastPat = Order()[lastOrd]; - Patterns[lastPat].Resize(lastRow + 1); + PATTERNINDEX lastPat = Order()[loopEndOrd]; + if(loopEndOrd == lastOrd) + Patterns[lastPat].Resize(loopEndRow + 1); if(restartRow != ROWINDEX_INVALID && !isEMIDI) { - Patterns[lastPat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, mpt::saturate_cast<ModCommand::PARAM>(restartRow)).Row(lastRow)); + Patterns[lastPat].WriteEffect(EffectWriter(CMD_PATTERNBREAK, mpt::saturate_cast<ModCommand::PARAM>(restartRow)).Row(loopEndRow)); + if(ORDERINDEX restartPos = Order().GetRestartPos(); loopEndOrd != lastOrd || restartPos <= std::numeric_limits<ModCommand::PARAM>::max()) + Patterns[lastPat].WriteEffect(EffectWriter(CMD_POSITIONJUMP, mpt::saturate_cast<ModCommand::PARAM>(restartPos)).Row(loopEndRow)); } } Order.SetSequence(0); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Load_stp.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Load_stp.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Load_stp.cpp 2021-03-17 19:51:21.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Load_stp.cpp 2021-08-01 23:12:39.000000000 +0200 @@ -406,6 +406,9 @@ channels = file.ReadUint16BE(); } + if(!file.CanRead(channels * patternLength * 4u)) + break; + if(!(loadFlags & loadPatternData) || !Patterns.Insert(actualPat, patternLength)) { file.Skip(channels * patternLength * 4u); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Message.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Message.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Message.cpp 2020-03-25 22:18:55.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Message.cpp 2021-08-02 18:48:33.000000000 +0200 @@ -21,7 +21,7 @@ // Read song message from a mapped file. // [in] data: pointer to the data in memory that is going to be read -// [in] length: number of characters that should be read, not including a possible trailing null terminator (it is automatically appended). +// [in] length: number of characters that should be read. Trailing null characters are automatically removed. // [in] lineEnding: line ending formatting of the text in memory. // [out] returns true on success. bool SongMessage::Read(const std::byte *data, size_t length, LineEnding lineEnding) @@ -36,18 +36,19 @@ // Simple line-ending detection algorithm. VERY simple. if(lineEnding == leAutodetect) { - char cprev = 0; size_t nCR = 0, nLF = 0, nCRLF = 0; // find CRs, LFs and CRLFs for(size_t i = 0; i < length; i++) { char c = str[i]; - if(c == '\r') nCR++; - else if(c == '\n') nLF++; + if(c == '\r') + nCR++; + else if(c == '\n') + nLF++; - if(i && cprev == '\r' && c == '\n') nCRLF++; - cprev = c; + if(i && str[i - 1] == '\r' && c == '\n') + nCRLF++; } // evaluate findings if(nCR == nLF && nCR == nCRLF) @@ -64,16 +65,15 @@ // calculate the final amount of characters to be allocated. for(size_t i = 0; i < length; i++) { - char c = str[i]; - - if(c != '\n' || lineEnding != leCRLF) - finalLength++; + finalLength++; + if(str[i] == '\r' && lineEnding == leCRLF) + i++; // skip the LF } - resize(finalLength); + clear(); + reserve(finalLength); - size_t cpos = 0; - for(size_t i = 0; i < length; i++, cpos++) + for(size_t i = 0; i < length; i++) { char c = str[i]; @@ -81,24 +81,25 @@ { case '\r': if(lineEnding != leLF) - at(cpos) = InternalLineEnding; + c = InternalLineEnding; else - at(cpos) = ' '; - if(lineEnding == leCRLF) i++; // skip the LF + c = ' '; + if(lineEnding == leCRLF) + i++; // skip the LF break; case '\n': if(lineEnding != leCR && lineEnding != leCRLF) - at(cpos) = InternalLineEnding; + c = InternalLineEnding; else - at(cpos) = ' '; + c = ' '; break; case '\0': - at(cpos) = ' '; + c = ' '; break; default: - at(cpos) = c; break; } + push_back(c); } return true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/ModInstrument.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/ModInstrument.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/ModInstrument.cpp 2020-11-14 14:49:06.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/ModInstrument.cpp 2021-08-08 15:22:27.000000000 +0200 @@ -299,6 +299,9 @@ if(!Resampling::IsKnownMode(resampling)) resampling = SRCMODE_DEFAULT; + + if(nMixPlug > MAX_MIXPLUGINS) + nMixPlug = 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Snd_defs.h new/libopenmpt-0.5.11+release.autotools/soundlib/Snd_defs.h --- old/libopenmpt-0.5.10+release.autotools/soundlib/Snd_defs.h 2021-04-24 15:20:50.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Snd_defs.h 2021-08-01 16:20:49.000000000 +0200 @@ -43,6 +43,7 @@ inline constexpr SmpLength MAX_SAMPLE_LENGTH = 0x10000000; // Sample length in frames. Sample size in bytes can be more than this (= 256 MB). inline constexpr ROWINDEX MAX_PATTERN_ROWS = 1024; +inline constexpr ROWINDEX MAX_ROWS_PER_BEAT = 65536; inline constexpr ORDERINDEX MAX_ORDERS = ORDERINDEX_MAX + 1; inline constexpr PATTERNINDEX MAX_PATTERNS = 4000; inline constexpr SAMPLEINDEX MAX_SAMPLES = 4000; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/Sndfile.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/Sndfile.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/Sndfile.cpp 2021-05-13 14:37:50.000000000 +0200 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/Sndfile.cpp 2021-08-08 15:22:27.000000000 +0200 @@ -484,6 +484,8 @@ LimitMax(ChnSettings[chn].nVolume, uint16(64)); if(ChnSettings[chn].nPan > 256) ChnSettings[chn].nPan = 128; + if(ChnSettings[chn].nMixPlugin > MAX_MIXPLUGINS) + ChnSettings[chn].nMixPlugin = 0; m_PlayState.Chn[chn].Reset(ModChannel::resetTotal, *this, chn, muteFlag); } @@ -550,8 +552,14 @@ LimitMax(m_nDefaultTempo, TEMPO(uint16_max, 0)); if(!m_nDefaultSpeed) m_nDefaultSpeed = 6; + if(m_nDefaultRowsPerMeasure < m_nDefaultRowsPerBeat) m_nDefaultRowsPerMeasure = m_nDefaultRowsPerBeat; + LimitMax(m_nDefaultRowsPerBeat, MAX_ROWS_PER_BEAT); + LimitMax(m_nDefaultRowsPerMeasure, MAX_ROWS_PER_BEAT); + if(!m_tempoSwing.empty()) + m_tempoSwing.resize(m_nDefaultRowsPerBeat); + m_PlayState.m_nMusicSpeed = m_nDefaultSpeed; m_PlayState.m_nMusicTempo = m_nDefaultTempo; m_PlayState.m_nCurrentRowsPerBeat = m_nDefaultRowsPerBeat; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libopenmpt-0.5.10+release.autotools/soundlib/pattern.cpp new/libopenmpt-0.5.11+release.autotools/soundlib/pattern.cpp --- old/libopenmpt-0.5.10+release.autotools/soundlib/pattern.cpp 2019-11-10 15:53:36.000000000 +0100 +++ new/libopenmpt-0.5.11+release.autotools/soundlib/pattern.cpp 2021-08-01 16:20:49.000000000 +0200 @@ -500,13 +500,14 @@ return; ssb.ReadItem(pat, "data", &ReadData); // pattern time signature - uint32 nRPB = 0, nRPM = 0; - ssb.ReadItem<uint32>(nRPB, "RPB."); - ssb.ReadItem<uint32>(nRPM, "RPM."); - pat.SetSignature(nRPB, nRPM); + uint32 rpb = 0, rpm = 0; + ssb.ReadItem<uint32>(rpb, "RPB."); + ssb.ReadItem<uint32>(rpm, "RPM."); + pat.SetSignature(rpb, rpm); TempoSwing swing; ssb.ReadItem<TempoSwing>(swing, "SWNG", TempoSwing::Deserialize); - if(!swing.empty()) swing.resize(nRPB); + if(!swing.empty()) + swing.resize(pat.GetRowsPerBeat()); pat.SetTempoSwing(swing); }