From 8a8784dd5a00331f9291d8dd7acc106655818183 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 28 Jun 2024 16:13:27 -0500 Subject: [PATCH] S3M import: fix crash on Android --- src/engine/fileOps/it.cpp | 10 ++++---- src/engine/fileOps/mod.cpp | 4 +-- src/engine/fileOps/s3m.cpp | 10 ++++---- src/engine/fileOps/xm.cpp | 8 +++--- src/engine/safeReader.cpp | 52 +++++++++++++++++++++++++++++++++++--- src/engine/safeReader.h | 11 ++++++++ 6 files changed, 75 insertions(+), 20 deletions(-) diff --git a/src/engine/fileOps/it.cpp b/src/engine/fileOps/it.cpp index bec1e9c30..e54ea6534 100644 --- a/src/engine/fileOps/it.cpp +++ b/src/engine/fileOps/it.cpp @@ -230,7 +230,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { throw EndOfFileException(&reader,reader.tell()); } - ds.name=reader.readString(26); + ds.name=reader.readStringLatin1(26); unsigned char hilight1=reader.readC(); unsigned char hilight2=reader.readC(); @@ -381,7 +381,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { return false; } - String dosName=reader.readString(12); + String dosName=reader.readStringLatin1(12); reader.readC(); // 0 @@ -441,7 +441,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { reader.readI(); } - ins->name=reader.readString(26); + ins->name=reader.readStringLatin1(26); if (compatTracker<0x200) { // old format // x @@ -554,7 +554,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { return false; } - String dosName=reader.readString(12); + String dosName=reader.readStringLatin1(12); reader.readC(); // 0 @@ -562,7 +562,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { unsigned char flags=reader.readC(); defVol[i]=reader.readC(); - s->name=reader.readString(26); + s->name=reader.readStringLatin1(26); unsigned char convert=reader.readC(); unsigned char defPan=reader.readC(); diff --git a/src/engine/fileOps/mod.cpp b/src/engine/fileOps/mod.cpp index 7198ca5c8..6065b2454 100644 --- a/src/engine/fileOps/mod.cpp +++ b/src/engine/fileOps/mod.cpp @@ -96,7 +96,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { logD("couldn't seek to 0"); throw EndOfFileException(&reader,reader.tell()); } - ds.name=reader.readString(20); + ds.name=reader.readStringLatin1(20); logI("%s",ds.name); // samples @@ -105,7 +105,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { for (int i=0; idepth=DIV_SAMPLE_DEPTH_8BIT; - sample->name=reader.readString(22); + sample->name=reader.readStringLatin1(22); logD("%d: %s",i+1,sample->name); int slen=((unsigned short)reader.readS_BE())*2; sampLens[i]=slen; diff --git a/src/engine/fileOps/s3m.cpp b/src/engine/fileOps/s3m.cpp index 13d946a8c..0c3878b00 100644 --- a/src/engine/fileOps/s3m.cpp +++ b/src/engine/fileOps/s3m.cpp @@ -117,7 +117,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { return false; } - ds.name=reader.readString(28); + ds.name=reader.readStringLatin1(28); reader.readC(); // 0x1a if (reader.readC()!=16) { @@ -366,7 +366,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { return false; } - String name=reader.readString(28); + String name=reader.readStringLatin1(28); ins->name=name; ds.ins.push_back(ins); @@ -401,7 +401,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { } } - String dosName=reader.readString(12); + String dosName=reader.readStringLatin1(12); if (ins->type==DIV_INS_ES5506) { unsigned int memSeg=0; @@ -434,7 +434,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { reader.readI(); reader.readI(); - String name=reader.readString(28); + String name=reader.readStringLatin1(28); s->name=dosName; ins->name=name; @@ -581,7 +581,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { // x reader.seek(12,SEEK_CUR); - String name=reader.readString(28); + String name=reader.readStringLatin1(28); ins->name=name; // "SCRI" diff --git a/src/engine/fileOps/xm.cpp b/src/engine/fileOps/xm.cpp index a451e7f1f..8ec1b7696 100644 --- a/src/engine/fileOps/xm.cpp +++ b/src/engine/fileOps/xm.cpp @@ -55,12 +55,12 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { throw EndOfFileException(&reader,reader.tell()); } - ds.name=reader.readString(20); + ds.name=reader.readStringLatin1(20); // 0x1a reader.readC(); - String trackerName=reader.readString(20); + String trackerName=reader.readStringLatin1(20); unsigned short trackerVer=reader.readS(); if (trackerName!="") logV("made with %s",trackerName); @@ -230,7 +230,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { headerSeek=reader.tell(); headerSeek+=reader.readI(); - ins->name=reader.readString(22); + ins->name=reader.readStringLatin1(22); ins->type=DIV_INS_AMIGA; ins->amiga.useNoteMap=true; @@ -341,7 +341,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { reader.readC(); // reserved - s->name=reader.readString(22); + s->name=reader.readStringLatin1(22); // load sample data s->depth=(flags&4)?DIV_SAMPLE_DEPTH_16BIT:DIV_SAMPLE_DEPTH_8BIT; diff --git a/src/engine/safeReader.cpp b/src/engine/safeReader.cpp index 09c012a5f..98f06f417 100644 --- a/src/engine/safeReader.cpp +++ b/src/engine/safeReader.cpp @@ -229,7 +229,7 @@ double SafeReader::readD() { } #endif -String SafeReader::readString(size_t stlen) { +String SafeReader::readStringWithEncoding(DivStringEncoding encoding, size_t stlen) { String ret; #ifdef READ_DEBUG logD("SR: reading string len %d at %x",stlen,curSeek); @@ -243,23 +243,67 @@ String SafeReader::readString(size_t stlen) { if (c==0) { zero=true; } - if (!zero) ret.push_back(c); + if (!zero) { + if (encoding==DIV_ENCODING_LATIN1) { + if (c>=0x20) { + if (c&0x80) { + if (c>=0xa0) { + ret.push_back(0xc0|(c>>6)); + ret.push_back(0x80|(c&63)); + } + } else { + ret.push_back(c); + } + } + } else { + ret.push_back(c); + } + } curPos++; } return ret; } -String SafeReader::readString() { +String SafeReader::readStringWithEncoding(DivStringEncoding encoding) { String ret; unsigned char c; if (isEOF()) throw EndOfFileException(this, len); while (!isEOF() && (c=readC())!=0) { - ret.push_back(c); + if (encoding==DIV_ENCODING_LATIN1) { + if (c>=0x20) { + if (c&0x80) { + if (c>=0xa0) { + ret.push_back(0xc0|(c>>6)); + ret.push_back(0x80|(c&63)); + } + } else { + ret.push_back(c); + } + } + } else { + ret.push_back(c); + } } return ret; } +String SafeReader::readString() { + return readStringWithEncoding(DIV_ENCODING_NONE); +} + +String SafeReader::readString(size_t stlen) { + return readStringWithEncoding(DIV_ENCODING_NONE,stlen); +} + +String SafeReader::readStringLatin1() { + return readStringWithEncoding(DIV_ENCODING_LATIN1); +} + +String SafeReader::readStringLatin1(size_t stlen) { + return readStringWithEncoding(DIV_ENCODING_LATIN1,stlen); +} + String SafeReader::readStringLine() { String ret; unsigned char c; diff --git a/src/engine/safeReader.h b/src/engine/safeReader.h index 7ab5e6b81..4d195f43d 100644 --- a/src/engine/safeReader.h +++ b/src/engine/safeReader.h @@ -29,6 +29,13 @@ enum Endianness { BigEndian }; +enum DivStringEncoding { + DIV_ENCODING_NONE=0, + DIV_ENCODING_UTF8, + DIV_ENCODING_LATIN1, + DIV_ENCODING_SHIFT_JIS +}; + class SafeReader; struct EndOfFileException { @@ -64,8 +71,12 @@ class SafeReader { float readF_BE(); double readD(); double readD_BE(); + String readStringWithEncoding(DivStringEncoding encoding); + String readStringWithEncoding(DivStringEncoding encoding, size_t len); String readString(); String readString(size_t len); + String readStringLatin1(); + String readStringLatin1(size_t len); String readStringLine(); String readStringToken(unsigned char delim, bool stripContiguous); String readStringToken();