From 5e78a489212ec8ecc9e728b24f1b264578e70354 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 15 Jan 2026 13:54:56 -0500 Subject: [PATCH] check groove/speed/virtual tempo bounds reject bad values --- src/engine/fileOps/fur.cpp | 5 +++++ src/engine/song.cpp | 14 ++++++++++++++ src/engine/song.h | 1 + 3 files changed, 20 insertions(+) diff --git a/src/engine/fileOps/fur.cpp b/src/engine/fileOps/fur.cpp index 60804ba8d..f165f6b0d 100644 --- a/src/engine/fileOps/fur.cpp +++ b/src/engine/fileOps/fur.cpp @@ -1545,6 +1545,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { if (ds.version>=96) { subSong->virtualTempoN=reader.readS(); subSong->virtualTempoD=reader.readS(); + + if (subSong->virtualTempoN<1) subSong->virtualTempoN=1; + if (subSong->virtualTempoD<1) subSong->virtualTempoD=1; } else { reader.readI(); } @@ -1638,6 +1641,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { for (int i=0; i<16; i++) { subSong->speeds.val[i]=(unsigned char)reader.readC(); } + subSong->speeds.checkBounds(); // grooves unsigned char grooveCount=reader.readC(); @@ -1648,6 +1652,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { for (int j=0; j<16; j++) { gp.val[j]=(unsigned char)reader.readC(); } + gp.checkBounds(); ds.grooves.push_back(gp); } diff --git a/src/engine/song.cpp b/src/engine/song.cpp index b65145550..fd9951dd1 100644 --- a/src/engine/song.cpp +++ b/src/engine/song.cpp @@ -482,10 +482,14 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) { virtualTempoN=reader.readS(); virtualTempoD=reader.readS(); + if (virtualTempoN<1) virtualTempoN=1; + if (virtualTempoD<1) virtualTempoD=1; + speeds.len=reader.readC(); for (int i=0; i<16; i++) { speeds.val[i]=reader.readS(); } + speeds.checkBounds(); name=reader.readString(); notes=reader.readString(); @@ -545,6 +549,9 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) { if (version>=96) { virtualTempoN=reader.readS(); virtualTempoD=reader.readS(); + + if (virtualTempoN<1) virtualTempoN=1; + if (virtualTempoD<1) virtualTempoD=1; } else { reader.readI(); } @@ -591,6 +598,7 @@ bool DivSubSong::readData(SafeReader& reader, int version, int chans) { for (int i=0; i<16; i++) { speeds.val[i]=(unsigned char)reader.readC(); } + speeds.checkBounds(); } for (int i=0; i<16; i++) { @@ -1031,6 +1039,11 @@ void DivSong::unload() { subsong.clear(); } +void DivGroovePattern::checkBounds() { + if (len<1) len=1; + if (len>16) len=16; +} + bool DivGroovePattern::readData(SafeReader& reader) { unsigned char magic[4]; @@ -1046,6 +1059,7 @@ bool DivGroovePattern::readData(SafeReader& reader) { for (int i=0; i<16; i++) { val[i]=reader.readS(); } + checkBounds(); return true; } diff --git a/src/engine/song.h b/src/engine/song.h index 71e38cd2e..828e52304 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -63,6 +63,7 @@ struct DivGroovePattern { unsigned short len; bool readData(SafeReader& reader); void putData(SafeWriter* w); + void checkBounds(); DivGroovePattern(): len(1) { for (int i=0; i<16; i++) {