From 68f7be0f232e4a48d53bc0b230120f9d1b909d94 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Fri, 24 Mar 2023 09:08:34 +0000 Subject: [PATCH] [od] add libmodplug patches These are patches for libmodplug that fix various UB issues. They come from these PRs to the upstream repository: 1. https://github.com/Konstanty/libmodplug/pull/92 2. https://github.com/Konstanty/libmodplug/pull/93 The upstream maintainer has not merged any PRs in over a year. Fixes #105. --- ...Fix-UB-when-calling-cctype-functions.patch | 959 ++++++++++++++ ...002-Fix-wformat-overflow-in-ABC_Init.patch | 43 + .../0003-avoid-unaligned-loads-stores.patch | 1125 +++++++++++++++++ ...med.cpp-avoid-unaligned-loads-stores.patch | 551 ++++++++ 4 files changed, 2678 insertions(+) create mode 100644 board/opendingux/patches/libmodplug/0001-Fix-UB-when-calling-cctype-functions.patch create mode 100644 board/opendingux/patches/libmodplug/0002-Fix-wformat-overflow-in-ABC_Init.patch create mode 100644 board/opendingux/patches/libmodplug/0003-avoid-unaligned-loads-stores.patch create mode 100644 board/opendingux/patches/libmodplug/0004-load_med.cpp-avoid-unaligned-loads-stores.patch diff --git a/board/opendingux/patches/libmodplug/0001-Fix-UB-when-calling-cctype-functions.patch b/board/opendingux/patches/libmodplug/0001-Fix-UB-when-calling-cctype-functions.patch new file mode 100644 index 000000000000..dcc99578b7b8 --- /dev/null +++ b/board/opendingux/patches/libmodplug/0001-Fix-UB-when-calling-cctype-functions.patch @@ -0,0 +1,959 @@ +From dc6d5994b4912cb00d0d183b400edfd656d6530c Mon Sep 17 00:00:00 2001 +From: Gleb Mazovetskiy +Date: Wed, 21 Dec 2022 11:44:27 +0000 +Subject: [PATCH 1/4] Fix UB when calling cctype functions + +Calling cctype functions, such as isspace, with negative values +is undefined behaviour. + +While glibc allows it, it crashes on uClibc compiled without +`UCLIBC_HAS_CTYPE_SIGNED`. + +Fixes the undefined behaviour by casting all arguments to +cctype functions to `unsigned char`. + +Signed-off-by: Gleb Mazovetskiy +--- + src/load_abc.cpp | 284 +++++++++++++++++++++++------------------------ + src/load_mid.cpp | 2 +- + src/load_pat.cpp | 30 ++--- + 3 files changed, 158 insertions(+), 158 deletions(-) + +diff --git a/src/load_abc.cpp b/src/load_abc.cpp +index b45f972..8444bd8 100644 +--- a/src/load_abc.cpp ++++ b/src/load_abc.cpp +@@ -260,13 +260,13 @@ static uint32_t abc_pattracktime(ABCHANDLE *h, uint32_t tracktime); + static int abc_patno(ABCHANDLE *h, uint32_t tracktime); + + +-static int abc_isvalidchar(char c) { ++static int abc_isvalidchar(unsigned char c) { + return(isalpha(c) || isdigit(c) || isspace(c) || c == '%' || c == ':'); + } + #if 0 + static const char *abc_skipspace(const char *p) + { +- while (*p && isspace(*p)) ++ while (*p && isspace(static_cast(*p))) + p++; + return p; + } +@@ -275,7 +275,7 @@ static const char *abc_skipspace(const char *p) + static void abc_extractkeyvalue(char *key, size_t key_max, + char *value, size_t value_max, const char *src) + { +- while (*src && isspace(*src)) ++ while (*src && isspace(static_cast(*src))) + src++; + + size_t key_size; +@@ -286,17 +286,17 @@ static void abc_extractkeyvalue(char *key, size_t key_max, + } + key[key_size++] = *src++; + } +- while (key_size > 0 && isspace(key[key_size - 1])) ++ while (key_size > 0 && isspace(static_cast(key[key_size - 1]))) + key_size--; + key[key_size] = '\0'; + +- while (*src && isspace(*src)) ++ while (*src && isspace(static_cast(*src))) + src++; + + size_t value_size; + for (value_size = 0; value_size < value_max - 1 && *src;) + value[value_size++] = *src++; +- while (value_size > 0 && isspace(value[value_size - 1])) ++ while (value_size > 0 && isspace(static_cast(value[value_size - 1]))) + value_size--; + value[value_size] = '\0'; + +@@ -359,7 +359,7 @@ static void abc_dumptracks(ABCHANDLE *h, const char *p) + nn[0] = "CCCDDEFFGGAABccddeffggaabb"[e->par[chordnote]]; + nn[1] = "b # # # # # # # # # # #"[e->par[chordnote]]; + nn[2] = '\0'; +- if( isspace(nn[1]) ) nn[1] = '\0'; ++ if( isspace(static_cast(nn[1])) ) nn[1] = '\0'; + printf("CMD %c: gchord %s%s", + (char)(e->cmd), nn, chordname[e->par[chordnum]]); + if( e->par[chordbase] != e->par[chordnote] ) { +@@ -557,7 +557,7 @@ static void abc_new_umacro(ABCHANDLE *h, const char *m) + ABCMACRO *retval, *mp; + char key[256], value[256]; + abc_extractkeyvalue(key, sizeof(key), value, sizeof(value), m); +- if( strlen(key) > 1 || strchr("~HIJKLMNOPQRSTUVWXY",toupper(key[0])) == 0 ) return; ++ if( strlen(key) > 1 || strchr("~HIJKLMNOPQRSTUVWXY",toupper(static_cast(key[0]))) == 0 ) return; + while( char *q = strchr(key, '!') ) + *q = '+'; // translate oldstyle to newstyle + if( !strcmp(key,"+nil+") ) { // delete a macro +@@ -823,7 +823,7 @@ static ABCTRACK *abc_locate_track(ABCHANDLE *h, const char *voice, int pos) + char vc[21]; + int i, trans=0, voiceno=0, instrno = 1, channo = 0; + for( ; *voice == ' '; voice++ ) ; // skip leading spaces +- for( i=0; i+1 < (int) sizeof(vc) && *voice && *voice != ']' && *voice != '%' && !isspace(*voice); voice++ ) // can work with inline voice instructions ++ for( i=0; i+1 < (int) sizeof(vc) && *voice && *voice != ']' && *voice != '%' && !isspace(static_cast(*voice)); voice++ ) // can work with inline voice instructions + vc[i++] = *voice; + vc[i] = '\0'; + prev = NULL; +@@ -1250,32 +1250,32 @@ static int abc_add_noteon(ABCHANDLE *h, int ch, const char *p, uint32_t tracktim + switch(ch) { + case '^': + if( p[0] == '^' ) { +- n = p[1]; ++ n = static_cast(p[1]); + i = 2; + ch = 'x'; + } + else { +- n = p[0]; ++ n = static_cast(p[0]); + i = 1; + } + break; + case '_': + if( p[0] == '_' ) { +- n = p[1]; ++ n = static_cast(p[1]); + i = 2; + ch = 'b'; + } + else { +- n = p[0]; ++ n = static_cast(p[0]); + i = 1; + } + break; + case '=': +- n = p[0]; ++ n = static_cast(p[0]); + i = 1; + break; + default: +- n = ch; ++ n = static_cast(ch); + i = 0; + break; + } +@@ -1332,7 +1332,7 @@ static int abc_add_noteon(ABCHANDLE *h, int ch, const char *p, uint32_t tracktim + } + else + d[note] = 0; // someone has doen ^X3 or something like it... +- while( p[i] && strchr(",'",p[i]) ) { ++ while( p[i] && strchr(",'",static_cast(p[i])) ) { + if( p[i]==',' ) oct--; + else oct++; + i++; +@@ -1381,7 +1381,7 @@ static int abc_add_noteon(ABCHANDLE *h, int ch, const char *p, uint32_t tracktim + } + } + tp->tienote->tiednote = 1; // mark him for the pattern writers +- for( j=i; isdigit(p[j]) || p[j]=='/'; j++ ) ; // look ahead to see if this one is tied too ++ for( j=i; isdigit(static_cast(p[j])) || p[j]=='/'; j++ ) ; // look ahead to see if this one is tied too + if( p[j] != '-' ) // is this note tied too? + tp->tienote = NULL; // if not the tie ends here... + return i; +@@ -1603,7 +1603,7 @@ static int abc_getnumber(const char *p, int *number) + int i,h; + i = 0; + h = 0; +- while( isdigit(p[i]) ) { ++ while( isdigit(static_cast(p[i])) ) { + if (i < 9) + h = 10 * h + p[i] - '0'; + i++; +@@ -1619,7 +1619,7 @@ static int abc_getexpr(const char *p, int *number) + { + int i, term, total; + i = 0; +- while( isspace(p[i]) ) ++ while( isspace(static_cast(p[i])) ) + i++; + if( p[i] == '(' ) { + i += abc_getexpr(p+i+1, number); +@@ -1628,12 +1628,12 @@ static int abc_getexpr(const char *p, int *number) + return i; + } + i += abc_getnumber(p+i, &total); +- while( isspace(p[i]) ) ++ while( isspace(static_cast(p[i])) ) + i++; + while( p[i] == '+' ) { + i += 1 + abc_getexpr(p+i+1, &term); + total += term; +- while( isspace(p[i]) ) ++ while( isspace(static_cast(p[i])) ) + i++; + } + *number = total; +@@ -1649,7 +1649,7 @@ static int abc_notelen(const char *p, int *len, int *div) + h *= 2; + i++; + } +- if( isdigit(p[i]) ) { ++ if( isdigit(static_cast(p[i])) ) { + h /= 2; + i += abc_getnumber(p+i,&k); + } +@@ -1738,7 +1738,7 @@ static int abc_extract_tempo(const char *p, int invoice) + case '=': + break; + default: +- if( isdigit(*q) ) { ++ if( isdigit(static_cast(*q)) ) { + if( state ) { + q+=abc_getnumber(q,&nd1)-1; + state = 0; +@@ -1812,10 +1812,10 @@ static void abc_set_parts(char **d, char *p) + j=0; + k=0; + for( i=0; p[i] && p[i] != '%'; i++ ) { +- if( isupper(p[i]) ) { ++ if( isupper(static_cast(p[i])) ) { + j++; + } +- if( isdigit(p[i]) ) { ++ if( isdigit(static_cast(p[i])) ) { + n=abc_getnumber(p+i, &k); + if( k == 0 ) + k = 1; +@@ -1833,7 +1833,7 @@ static void abc_set_parts(char **d, char *p) + // now copy bytes from p to *d, taking parens and digits in account + j = 0; + for( i=0; p[i] && p[i] != '%' && j < size && i < (int)size; i++ ) { +- if( isdigit(p[i]) || isupper(p[i]) || p[i] == '(' || p[i] == ')' ) { ++ if( isdigit(static_cast(p[i])) || isupper(static_cast(p[i])) || p[i] == '(' || p[i] == ')' ) { + if( p[i] == ')' ) { + for( n=j; n > 0 && q[n-1] != '('; n-- ) ; // find open paren in q + // q[n+1] to q[j] contains the substring that must be repeated +@@ -1856,7 +1856,7 @@ static void abc_set_parts(char **d, char *p) + } + continue; + } +- if( isdigit(p[i]) ) { ++ if( isdigit(static_cast(p[i])) ) { + n = abc_getnumber(p+i,&k); + i += n - 1; + // if nothing is ready to 'repeat', skip it. +@@ -2243,7 +2243,7 @@ static void abc_preprocess(ABCHANDLE *h, ABCMACRO *m) + char *p = s; + for( j=0; jsubst[j]; +- if( a > 'g' && islower(a) ) { ++ if( a > 'g' && islower(static_cast(a)) ) { + b = a - 'n'; + a = "CDEFGABCDEFGABcdefgabcdefgabcdefgab"[i+b+7]; + *p++ = a; +@@ -2339,11 +2339,11 @@ BOOL CSoundFile::TestABC(const BYTE *lpStream, DWORD dwMemLength) + } + if(id[0]=='K' + && id[1]==':' +- && (isalpha(id[2]) || isspace(id[2])) ) return 1; ++ && (isalpha(static_cast(id[2])) || isspace(static_cast(id[2]))) ) return 1; + // disable binary error if have any "tag" + if((id[0]>='A' && id[0]<='Z') + && id[1]==':' +- && (isalpha(id[2]) || isspace(id[2])) ) hasText = 1; ++ && (isalpha(static_cast(id[2])) || isspace(static_cast(id[2]))) ) hasText = 1; + } + return 0; + } +@@ -2367,7 +2367,7 @@ static ABCHANDLE *ABC_Init(void) + retval->barticks = 0; + p = getenv(ABC_ENV_NORANDOMPICK); + if( p ) { +- if( isdigit(*p) ) ++ if( isdigit(static_cast(*p)) ) + retval->pickrandom = atoi(p); + if( *p == '-' ) { + retval->pickrandom = atoi(p+1)-1; // xmms preloads the file +@@ -2652,12 +2652,12 @@ static int ABC_Key(const char *p) + int i,j; + char c[8]; + const char *q; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + q = p; + memset(c, 0, 8); + for( i=0; i<8 && *p && *p != ']'; p++ ) { +- if( isspace(*p) ) { +- while( isspace(*p) ) p++; ++ if( isspace(static_cast(*p)) ) { ++ while( isspace(static_cast(*p)) ) p++; + if( strncasecmp(p, "min", 3) && strncasecmp(p, "maj", 3) ) + break; + } +@@ -2687,9 +2687,9 @@ static int ABC_Key(const char *p) + + static char *abc_skip_word(char *p) + { +- while( isspace(*p) ) p++; +- while( *p && !isspace(*p) && *p != ']') p++; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; ++ while( *p && !isspace(static_cast(*p)) && *p != ']') p++; ++ while( isspace(static_cast(*p)) ) p++; + return p; + } + +@@ -2798,7 +2798,7 @@ static void abc_setup_chordnames() + static int abc_MIDI_getnumber(const char *p) + { + int n; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + abc_getnumber(p, &n); + if( n < 0 ) n = 0; + if( n > 127 ) n = 127; +@@ -2808,7 +2808,7 @@ static int abc_MIDI_getnumber(const char *p) + static int abc_MIDI_getprog(const char *p) + { + int n; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + abc_getnumber(p, &n); + if( n < 1 ) n = 1; + if( n > 128 ) n = 128; +@@ -2819,32 +2819,32 @@ static int abc_MIDI_getprog(const char *p) + static void abc_MIDI_drone(const char *p, int *gm, int *ptch, int *vol) + { + int i; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + p += abc_getnumber(p, &i); + i++; // adjust for 1..128 + if( i>0 && i < 129 ) + *gm = i; + else + *gm = 71; // bassoon +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + p += abc_getnumber(p, &i); + if( i>0 && i < 127 ) + ptch[0] = i; + else + ptch[0] = 45; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + p += abc_getnumber(p, &i); + if( i>0 && i < 127 ) + ptch[1] = i; + else + ptch[1] = 33; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + p += abc_getnumber(p, &i); + if( i>0 && i < 127 ) + vol[0] = i; + else + vol[0] = 80; +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + p += abc_getnumber(p, &i); + if( i>0 && i < 127 ) + vol[1] = i; +@@ -2869,8 +2869,8 @@ static void abc_MIDI_channel(const char *p, ABCTRACK *tp, ABCHANDLE *h) + { + int i1, i2; + i1 = tp? tp->vno: 1; +- for( ; *p && isspace(*p); p++ ) ; +- if( isdigit(*p) ) { ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; ++ if( isdigit(static_cast(*p)) ) { + p += abc_getnumber(p, &i2); + if( i2 >= 1 && i2 <= 16 ) + abc_chan_to_tracks(h, i1, i2); // we start at 1 +@@ -2894,11 +2894,11 @@ static void abc_MIDI_program(const char *p, ABCTRACK *tp, ABCHANDLE *h) + { + int i1, i2; + i1 = tp? tp->vno: 1; +- for( ; *p && isspace(*p); p++ ) ; +- if( isdigit(*p) ) { ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; ++ if( isdigit(static_cast(*p)) ) { + p += abc_getnumber(p, &i2); +- for( ; *p && isspace(*p); p++ ) ; +- if( isdigit(*p) ) { ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; ++ if( isdigit(static_cast(*p)) ) { + i1 = i2; + abc_getnumber(p, &i2); + } +@@ -2919,25 +2919,25 @@ static void abc_mute_voice(ABCHANDLE *h, ABCTRACK *tp, int m) + static void abc_MIDI_voice(const char *p, ABCTRACK *tp, ABCHANDLE *h) + { + int i1, i2; +- for( ; *p && isspace(*p); p++ ) ; ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; + if( strncmp(p,"instrument=",11) && strncmp(p,"mute",4) ) { + tp = abc_locate_track(h, p, 0); +- for( ; *p && !isspace(*p); p++ ) ; +- for( ; *p && isspace(*p); p++ ) ; ++ for( ; *p && !isspace(static_cast(*p)); p++ ) ; ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; + } + i1 = tp? tp->vno: 1; + i2 = 0; +- if( !strncmp(p,"instrument=",11) && isdigit(p[11]) ) { ++ if( !strncmp(p,"instrument=",11) && isdigit(static_cast(p[11])) ) { + p += 11; + p += abc_getnumber(p, &i2); +- for( ; *p && isspace(*p); p++ ) ; +- if( !strncmp(p,"bank=",5) && isdigit(p[5]) ) { +- for( ; *p && !isspace(*p); p++ ) ; +- for( ; *p && isspace(*p); p++ ) ; ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; ++ if( !strncmp(p,"bank=",5) && isdigit(static_cast(p[5])) ) { ++ for( ; *p && !isspace(static_cast(*p)); p++ ) ; ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; + } + } + if( tp ) abc_mute_voice(h,tp,0); +- if( !strncmp(p,"mute",4) && (p[4]=='\0' || p[4]=='%' || isspace(p[4])) ) { ++ if( !strncmp(p,"mute",4) && (p[4]=='\0' || p[4]=='%' || isspace(static_cast(p[4]))) ) { + if( tp ) abc_mute_voice(h,tp,1); + } + abc_instr_to_tracks(h, i1, i2); // starts already at 1 (draft 4.0) +@@ -2949,7 +2949,7 @@ static void abc_MIDI_chordname(const char *p) + char name[20]; + int i; + +- for(; *p && isspace(*p); p++) ++ for(; *p && isspace(static_cast(*p)); p++) + ; + i = 0; + while ((i < 19) && (*p != ' ') && (*p != '\0')) { +@@ -2965,8 +2965,8 @@ static void abc_MIDI_chordname(const char *p) + int notes[6]; + i = 0; + memset(notes, 0, sizeof(notes)); +- while ((i < 6) && isspace(*p)) { +- for(; *p && isspace(*p); p++) ++ while ((i < 6) && isspace(static_cast(*p))) { ++ for(; *p && isspace(static_cast(*p)); p++) + ; + p += abc_getnumber(p, ¬es[i]); + i = i + 1; +@@ -2981,21 +2981,21 @@ static int abc_MIDI_drum(const char *p, ABCHANDLE *h) + { + char *q; + int i, n, m, len; +- while( isspace(*p) ) p++; +- if( !strncmp(p,"on",2) && (isspace(p[2]) || p[2] == '\0') ) return 2; +- if( !strncmp(p,"off",3) && (isspace(p[3]) || p[3] == '\0') ) return 1; ++ while( isspace(static_cast(*p)) ) p++; ++ if( !strncmp(p,"on",2) && (isspace(static_cast(p[2])) || p[2] == '\0') ) return 2; ++ if( !strncmp(p,"off",3) && (isspace(static_cast(p[3])) || p[3] == '\0') ) return 1; + n = 0; len = 0; +- for( q = h->drum; *p && !isspace(*p); p++ ) { ++ for( q = h->drum; *p && !isspace(static_cast(*p)); p++ ) { + if( !strchr("dz0123456789",*p) ) break; + *q++ = *p; len++; +- if( !isdigit(*p) && len < (int)sizeof(h->drum)-1 ) { +- if( !isdigit(p[1]) ) { *q++ = '1'; len ++; } ++ if( !isdigit(static_cast(*p)) && len < (int)sizeof(h->drum)-1 ) { ++ if( !isdigit(static_cast(p[1])) ) { *q++ = '1'; len ++; } + n++; // count the silences too.... + } + if (len >= (int)sizeof(h->drum)-1) { + // consume the rest of the input + // definitely enough "drum last state" stored. +- while ( *p && !isspace(*p) ) p++; ++ while ( *p && !isspace(static_cast(*p)) ) p++; + break; + } + } +@@ -3003,10 +3003,10 @@ static int abc_MIDI_drum(const char *p, ABCHANDLE *h) + q = h->drumins; + for( i = 0; idrum[i*2] == 'd' ) { +- while( *p && isspace(*p) ) p++; +- if( !isdigit(*p) ) { ++ while( *p && isspace(static_cast(*p)) ) p++; ++ if( !isdigit(static_cast(*p)) ) { + m = 0; +- while( *p && !isspace(*p) ) p++; ++ while( *p && !isspace(static_cast(*p)) ) p++; + } + else + p += abc_getnumber(p,&m); +@@ -3017,10 +3017,10 @@ static int abc_MIDI_drum(const char *p, ABCHANDLE *h) + q = h->drumvol; + for( i = 0; idrum[i*2] == 'd' ) { +- while( *p && isspace(*p) ) p++; +- if( !isdigit(*p) ) { ++ while( *p && isspace(static_cast(*p)) ) p++; ++ if( !isdigit(static_cast(*p)) ) { + m = 0; +- while( *p && !isspace(*p) ) p++; ++ while( *p && !isspace(static_cast(*p)) ) p++; + } + else + p += abc_getnumber(p,&m); +@@ -3036,17 +3036,17 @@ static int abc_MIDI_gchord(const char *p, ABCHANDLE *h) + { + char *q; + int len = 0; +- while( isspace(*p) ) p++; +- if( !strncmp(p,"on",2) && (isspace(p[2]) || p[2] == '\0') ) return 2; +- if( !strncmp(p,"off",3) && (isspace(p[3]) || p[3] == '\0') ) return 1; +- for( q = h->gchord; *p && !isspace(*p); p++ ) { ++ while( isspace(static_cast(*p)) ) p++; ++ if( !strncmp(p,"on",2) && (isspace(static_cast(p[2])) || p[2] == '\0') ) return 2; ++ if( !strncmp(p,"off",3) && (isspace(static_cast(p[3])) || p[3] == '\0') ) return 1; ++ for( q = h->gchord; *p && !isspace(static_cast(*p)); p++ ) { + if( !strchr("fbcz0123456789ghijGHIJ",*p) ) break; + *q++ = *p; len++; +- if( !isdigit(*p) && len < (int)sizeof(h->gchord)-1 && !isdigit(p[1]) ) { *q++ = '1'; len ++; } ++ if( !isdigit(static_cast(*p)) && len < (int)sizeof(h->gchord)-1 && !isdigit(static_cast(p[1])) ) { *q++ = '1'; len ++; } + if (len >= (int)sizeof(h->gchord)-1) { + // consume the rest of the input + // definitely enough "drum last state" stored. +- while ( *p && !isspace(*p) ) p++; ++ while ( *p && !isspace(static_cast(*p)) ) p++; + break; + } + } +@@ -3099,7 +3099,7 @@ static void abc_metric_gchord(ABCHANDLE *h, int mlen, int mdiv) + + static void abc_MIDI_legato(const char *p, ABCTRACK *tp) + { +- for( ; *p && isspace(*p); p++ ) ; ++ for( ; *p && isspace(static_cast(*p)); p++ ) ; + if( !strncmp(p,"off",3) ) tp->legato = 0; + else tp->legato = 1; + } +@@ -3130,7 +3130,7 @@ static int abc_drum_steps(const char *dch) + const char *p; + int i=0; + for( p=dch; *p; p++ ) { +- if( isdigit(*p) ) i += *p - '0';; ++ if( isdigit(static_cast(*p)) ) i += *p - '0';; + } + return i; + } +@@ -3185,7 +3185,7 @@ static int abc_gchord_steps(const char *gch) + const char *p; + int i=0; + for( p=gch; *p; p++ ) +- if( isdigit(*p) ) i += *p - '0'; ++ if( isdigit(static_cast(*p)) ) i += *p - '0'; + return i; + } + +@@ -3231,7 +3231,7 @@ static void abc_add_gchord(ABCHANDLE *h, uint32_t tracktime, uint32_t bartime) + stime = (tracktime - etime) * steps; + rtime = 0; + while( rtime < stime ) { +- gnote = h->gchord[2*g]; ++ gnote = static_cast(h->gchord[2*g]); + glen = h->gchord[2*g+1] - '0'; + if( ++g == gsteps ) g = 0; + switch(gnote) { +@@ -3313,7 +3313,7 @@ static void abc_MIDI_beat(ABCHANDLE *h, const char *p) + h->beat[2] = 110; + h->beat[3] = 1; + for( j=0; j<4; j++ ) { +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + if( *p ) { + p += abc_getnumber(p, &i); + if( i < 0 ) i = 0; +@@ -3336,7 +3336,7 @@ static void abc_MIDI_beat(ABCHANDLE *h, const char *p) + // %%MIDI beatstring fppmpmp + static void abc_MIDI_beatstring(ABCHANDLE *h, const char *p) + { +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) p++; + if( h->beatstring ) _mm_free(h->allochandle, h->beatstring); + if( strlen(p) ) + h->beatstring = DupStr(h->allochandle,p,strlen(p)+1); +@@ -3483,47 +3483,47 @@ static void abc_recalculate_tracktime(ABCHANDLE *h) { + static void abc_MIDI_command(ABCHANDLE *h, char *p, char delim) { + int t; + // interpret some of the possibilitys +- if( !strncmp(p,"bassprog",8) && isspace(p[8]) ) h->abcbassprog = abc_MIDI_getprog(p+8)+1; +- if( !strncmp(p,"bassvol",7) && isspace(p[7]) ) h->abcbassvol = abc_MIDI_getnumber(p+7); +- if( !strncmp(p,"beat",4) && isspace(p[4]) ) abc_MIDI_beat(h, p+4); +- if( !strncmp(p,"beatstring",10) && isspace(p[10]) ) abc_MIDI_beatstring(h, p+4); +- if( !strncmp(p,"chordname",9) && isspace(p[9]) ) abc_MIDI_chordname(p+9); +- if( !strncmp(p,"chordprog",9) && isspace(p[9]) ) h->abcchordprog = abc_MIDI_getprog(p+9)+1; +- if( !strncmp(p,"chordvol",8) && isspace(p[8]) ) h->abcchordvol = abc_MIDI_getnumber(p+8); +- if( !strncmp(p,"drone",5) && isspace(p[5]) ) abc_MIDI_drone(p+5, &h->dronegm, h->dronepitch, h->dronevol); +- if( !strncmp(p,"droneoff",8) && (p[8]=='\0' || p[8]==delim || isspace(p[8])) ) h->droneon = 0; +- if( !strncmp(p,"droneon",7) && (p[7]=='\0' || p[7]==delim || isspace(p[7])) ) h->droneon = 1; ++ if( !strncmp(p,"bassprog",8) && isspace(static_cast(p[8])) ) h->abcbassprog = abc_MIDI_getprog(p+8)+1; ++ if( !strncmp(p,"bassvol",7) && isspace(static_cast(p[7])) ) h->abcbassvol = abc_MIDI_getnumber(p+7); ++ if( !strncmp(p,"beat",4) && isspace(static_cast(p[4])) ) abc_MIDI_beat(h, p+4); ++ if( !strncmp(p,"beatstring",10) && isspace(static_cast(p[10])) ) abc_MIDI_beatstring(h, p+4); ++ if( !strncmp(p,"chordname",9) && isspace(static_cast(p[9])) ) abc_MIDI_chordname(p+9); ++ if( !strncmp(p,"chordprog",9) && isspace(static_cast(p[9])) ) h->abcchordprog = abc_MIDI_getprog(p+9)+1; ++ if( !strncmp(p,"chordvol",8) && isspace(static_cast(p[8])) ) h->abcchordvol = abc_MIDI_getnumber(p+8); ++ if( !strncmp(p,"drone",5) && isspace(static_cast(p[5])) ) abc_MIDI_drone(p+5, &h->dronegm, h->dronepitch, h->dronevol); ++ if( !strncmp(p,"droneoff",8) && (p[8]=='\0' || p[8]==delim || isspace(static_cast(p[8]))) ) h->droneon = 0; ++ if( !strncmp(p,"droneon",7) && (p[7]=='\0' || p[7]==delim || isspace(static_cast(p[7]))) ) h->droneon = 1; + t = h->drumon; +- if( !strncmp(p,"drum",4) && isspace(p[4]) ) { ++ if( !strncmp(p,"drum",4) && isspace(static_cast(p[4])) ) { + h->drumon = abc_MIDI_drum(p+4, h); + if( h->drumon ) --h->drumon; + else h->drumon = t; + } +- if( !strncmp(p,"drumoff",7) && (p[7]=='\0' || p[7]==delim || isspace(p[7])) ) h->drumon = 0; +- if( !strncmp(p,"drumon",6) && (p[6]=='\0' || p[6]==delim || isspace(p[6])) ) h->drumon = 1; ++ if( !strncmp(p,"drumoff",7) && (p[7]=='\0' || p[7]==delim || isspace(static_cast(p[7]))) ) h->drumon = 0; ++ if( !strncmp(p,"drumon",6) && (p[6]=='\0' || p[6]==delim || isspace(static_cast(p[6]))) ) h->drumon = 1; + if( t != h->drumon ) { + if( h->drumon && !h->tpr ) h->tpr = h->track; + if( h->tpr ) abc_add_drum_sync(h, h->tpr, h->tracktime); // don't start drumming from the beginning of time! + if( h->tpr && !h->drumon ) h->tpr = NULL; + } + t = h->gchordon; +- if( !strncmp(p,"gchord",6) && (p[6]=='\0' || p[6]==delim || isspace(p[6])) ) { ++ if( !strncmp(p,"gchord",6) && (p[6]=='\0' || p[6]==delim || isspace(static_cast(p[6]))) ) { + h->gchordon = abc_MIDI_gchord(p+6, h); + if( h->gchordon ) --h->gchordon; + else h->gchordon = t; + } +- if( !strncmp(p,"gchordoff",9) && (p[9]=='\0' || p[9]==delim || isspace(p[9])) ) h->gchordon = 0; +- if( !strncmp(p,"gchordon",8) && (p[8]=='\0' || p[8]==delim || isspace(p[8])) ) h->gchordon = 1; ++ if( !strncmp(p,"gchordoff",9) && (p[9]=='\0' || p[9]==delim || isspace(static_cast(p[9]))) ) h->gchordon = 0; ++ if( !strncmp(p,"gchordon",8) && (p[8]=='\0' || p[8]==delim || isspace(static_cast(p[8]))) ) h->gchordon = 1; + if( t != h->gchordon ) { + if( h->tpc ) abc_add_gchord_syncs(h, h->tpc, h->tracktime); + } +- if( !strncmp(p,"channel",7) && isspace(p[7]) ) ++ if( !strncmp(p,"channel",7) && isspace(static_cast(p[7])) ) + abc_MIDI_channel(p+8, h->tp = abc_check_track(h, h->tp), h); +- if( !strncmp(p,"program",7) && isspace(p[7]) ) ++ if( !strncmp(p,"program",7) && isspace(static_cast(p[7])) ) + abc_MIDI_program(p+8, h->tp = abc_check_track(h, h->tp), h); +- if( !strncmp(p,"voice",5) && isspace(p[5]) ) ++ if( !strncmp(p,"voice",5) && isspace(static_cast(p[5])) ) + abc_MIDI_voice(p+6, h->tp = abc_check_track(h, h->tp), h); +- if( !strncmp(p,"legato",6) && (p[6]=='\0' || p[6]==delim || isspace(p[6])) ) ++ if( !strncmp(p,"legato",6) && (p[6]=='\0' || p[6]==delim || isspace(static_cast(p[6]))) ) + abc_MIDI_legato(p+6, h->tp = abc_check_track(h, h->tp)); + } + +@@ -3548,13 +3548,13 @@ static char *abc_continuated(ABCHANDLE *h, MMFILE *mmf, char *p) { + abc_message("line not properly continued\n%s", p1); + return p1; + } +- while( *pm && isspace(*pm) ) ++pm; ++ while( *pm && isspace(static_cast(*pm)) ) ++pm; + if( !strncmp(pm,"%%",2) ) { +- for( p2 = pm+2; *p2 && isspace(*p2); p2++ ) ; +- if( !strncmp(p2,"MIDI",4) && (p2[4]=='=' || isspace(p2[4])) ) { +- for( p2+=5; *p2 && isspace(*p2); p2++ ) ; ++ for( p2 = pm+2; *p2 && isspace(static_cast(*p2)); p2++ ) ; ++ if( !strncmp(p2,"MIDI",4) && (p2[4]=='=' || isspace(static_cast(p2[4]))) ) { ++ for( p2+=5; *p2 && isspace(static_cast(*p2)); p2++ ) ; + if( *p2 == '=' ) +- for( p2+=1; *p2 && isspace(*p2); p2++ ) ; ++ for( p2+=1; *p2 && isspace(static_cast(*p2)); p2++ ) ; + abc_MIDI_command(h,p2,'%'); + } + continued = 1; +@@ -3685,7 +3685,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + abcxcount = 0; + mmfseek(mmfile,0,SEEK_SET); + while ((line=abc_gets(h, mmfile)) != NULL) { +- for( p=line; isspace(*p); p++ ) ; ++ for( p=line; isspace(static_cast(*p)); p++ ) ; + if( !strncmp(p,"X:",2) ) abcxcount++; + } + if( abcxcount == 0 ) +@@ -3699,7 +3699,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + mmsp--; + while ((line=abc_gets(h, mmstack[mmsp])) != NULL) { + char blankline[3] = "% "; +- for( p=line; isspace(*p); p++ ) ; ++ for( p=line; isspace(static_cast(*p)); p++ ) ; + switch(abcstate) { + case INSKIPFORX: + if( !strncmp(p,"X:",2) ) { +@@ -3711,7 +3711,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + if( !strncmp(p,"X:",2) ) { + abcstate = INHEAD; + memset(m_szNames[0], 0, 32); +- for( p+=2; isspace(*p); p++ ) ; ++ for( p+=2; isspace(static_cast(*p)); p++ ) ; + abcxnumber = atoi(p); + abchornpipe = 0; + h->droneon = 0; +@@ -3792,8 +3792,8 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + break; + } + if( !strncmp(p,"R:",2) ) { +- for( p+=2; isspace(*p); p++ ) ; +- if( !strncmp(p,"hornpipe",8) && (isspace(p[8]) || p[8]=='\0') ) abchornpipe = 1; ++ for( p+=2; isspace(static_cast(*p)); p++ ) ; ++ if( !strncmp(p,"hornpipe",8) && (isspace(static_cast(p[8])) || p[8]=='\0') ) abchornpipe = 1; + else abchornpipe = 0; + break; + } +@@ -3980,8 +3980,8 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + p[1]= '%'; + } + if( !strncmp(p,"%%",2) ) { +- for( p+=2; *p && isspace(*p); p++ ) ; +- if( !strncmp(p,"abc-include",11) && isspace(p[11]) ) { ++ for( p+=2; *p && isspace(static_cast(*p)); p++ ) ; ++ if( !strncmp(p,"abc-include",11) && isspace(static_cast(p[11])) ) { + for( t=12; isspace(p[t]); t++ ) ; + if( p[t] ) { + mmsp++; +@@ -3998,10 +3998,10 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + } + else abc_message("failure: abc-include missing file name, %s", p); + } +- if( !strncmp(p,"MIDI",4) && (p[4]=='=' || isspace(p[4])) && abcstate != INSKIPFORX ) { +- for( p+=5; *p && isspace(*p); p++ ) ; ++ if( !strncmp(p,"MIDI",4) && (p[4]=='=' || isspace(static_cast(p[4]))) && abcstate != INSKIPFORX ) { ++ for( p+=5; *p && isspace(static_cast(*p)); p++ ) ; + if( *p == '=' ) +- for( p+=1; *p && isspace(*p); p++ ) ; ++ for( p+=1; *p && isspace(static_cast(*p)); p++ ) ; + abc_MIDI_command(h,p,'%'); + if( h->tp ) abcnolegato = !h->tp->legato; + if( !abcnolegato ) abcnoslurs = 0; +@@ -4034,7 +4034,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + partpat[global_part - 'A'][1] = t; + // give every new coming abcevent the desired part indication + while( p[2]==' ' || p[2]=='.' ) p++; // skip blancs and dots +- if( isupper(p[2]) ) ++ if( isupper(static_cast(p[2])) ) + global_part = p[2]; + else + global_part = ' '; +@@ -4073,7 +4073,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + ch0 = ' '; + pp = 0; + while (*p && (ch = *p++) != '\0') { +- if( !pp && isalpha(ch) && *p != ':' ) { // maybe a macro ++ if( !pp && isalpha(static_cast(ch)) && *p != ':' ) { // maybe a macro + for( mp=h->umacro; mp; mp=mp->next ) { + if( ch == mp->name[0] ) { + pp = p; +@@ -4131,8 +4131,8 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + else + partpat[global_part - 'A'][1] = t; + // give every new coming abcevent the desired part indication +- while( isspace(p[2]) || p[2]=='.' ) p++; // skip blancs and dots +- if( isupper(p[2]) ) ++ while( isspace(static_cast(p[2])) || p[2]=='.' ) p++; // skip blancs and dots ++ if( isupper(static_cast(p[2])) ) + global_part = p[2]; + else + global_part = ' '; +@@ -4152,11 +4152,11 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + break; + } + if( !strncmp(p,"I:",2) ) { // interpret some of the possibilitys +- for( p += 2; isspace(*p); p++ ) ; +- if( !strncmp(p,"MIDI",4) && (p[4]=='=' || isspace(p[4])) ) { // interpret some of the possibilitys +- for( p += 4; isspace(*p); p++ ) ; ++ for( p += 2; isspace(static_cast(*p)); p++ ) ; ++ if( !strncmp(p,"MIDI",4) && (p[4]=='=' || isspace(static_cast(p[4]))) ) { // interpret some of the possibilitys ++ for( p += 4; isspace(static_cast(*p)); p++ ) ; + if( *p == '=' ) +- for( p += 1; isspace(*p); p++ ) ; ++ for( p += 1; isspace(static_cast(*p)); p++ ) ; + abc_MIDI_command(h, p, ']'); + if( h->tp ) abcnolegato = !h->tp->legato; + if( !abcnolegato ) abcnoslurs = 0; +@@ -4235,7 +4235,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + notelen *= cnotelen; + notediv *= cnotediv; + tupletr = abc_tuplet(¬elen, ¬ediv, tupletp, tupletq, tupletr); +- while( isspace(*p) ) p++; // allow spacing in broken rithm notation ++ while( isspace(static_cast(*p)) ) p++; // allow spacing in broken rithm notation + p += abc_brokenrithm(p, ¬elen, ¬ediv, &brokenrithm, abchornpipe); + thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv); + if( abcfermata ) { +@@ -4278,7 +4278,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + if( abceffoper != 255 ) abceffect = none; + break; + } +- if( isdigit(*p) ) { // different endings in repeats [i,j,n-r,s,... ++ if( isdigit(static_cast(*p)) ) { // different endings in repeats [i,j,n-r,s,... + h->tp = abc_check_track(h, h->tp); + abc_add_partbreak(h, h->tp, h->tracktime); + p += abc_getnumber(p, ¬elen); +@@ -4304,7 +4304,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + break; + case '(': // slurs follow or some tuplet (duplet, triplet etc.) + abcto = 0; +- if( isdigit(*p) ) { ++ if( isdigit(static_cast(*p)) ) { + p += abc_getnumber(p,&tupletp); + tupletr = tupletp; // ABC draft 2.0 (4.13): if r is not given it defaults to p + switch( tupletp ) { // ABC draft 2.0 (4.13): q defaults depending on p and time signature +@@ -4323,10 +4323,10 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + } + if( *p==':' ) { + p++; +- if( isdigit(*p) ) p += abc_getnumber(p,&tupletq); ++ if( isdigit(static_cast(*p)) ) p += abc_getnumber(p,&tupletq); + if( *p==':' ) { + p++; +- if( isdigit(*p) ) p += abc_getnumber(p,&tupletr); ++ if( isdigit(static_cast(*p)) ) p += abc_getnumber(p,&tupletr); + } + } + } +@@ -4375,7 +4375,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + sprintf(barsig, "%s%s", sig[abckey], sig[abckey]); // reset the key signature + bartime = h->tracktime; + if( h->tp && h->tp->vpos ) h->tp = abc_locate_track(h, h->tp->v, 0); // reset from voice overlay +- if( isdigit(*p) ) { // different endings in repeats |i,j,n-r,s,... ++ if( isdigit(static_cast(*p)) ) { // different endings in repeats |i,j,n-r,s,... + h->tp = abc_check_track(h, h->tp); + abc_add_partbreak(h, h->tp, h->tracktime); + p += abc_getnumber(p, ¬elen); +@@ -4426,7 +4426,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + } + break; + case '"': // chord notation +- if( !strchr("_^<>@", *p) && !isdigit(*p) ) { // if it's not a annotation string ++ if( !strchr("_^<>@", *p) && !isdigit(static_cast(*p)) ) { // if it's not a annotation string + h->tp = abc_check_track(h, h->tp); + if( !h->tpc ) h->tpc = abc_locate_track(h, h->tp->v, 0); + if( h->tp == h->tpc ) abc_add_chord(p, h, h->tpc, h->tracktime); // only do chords for one voice +@@ -4443,8 +4443,8 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + abcto = -1; + } + else +- if( !isspace(*p) ) abcto = 0; +- if( !strncasecmp(p,"to",2) && (isspace(p[2]) || p[2] == '"') ) abcto = 1; ++ if( !isspace(static_cast(*p)) ) abcto = 0; ++ if( !strncasecmp(p,"to",2) && (isspace(static_cast(p[2])) || p[2] == '"') ) abcto = 1; + } + if( !ch ) abcstate = INSKIPFORQUOTE; + break; +@@ -4665,7 +4665,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + h->tp->tienote = h->tp->tail; + } + tupletr = abc_tuplet(¬elen, ¬ediv, tupletp, tupletq, tupletr); +- while( isspace(*p) ) p++; // allow spacing in broken rithm notation ++ while( isspace(static_cast(*p)) ) p++; // allow spacing in broken rithm notation + p += abc_brokenrithm(p, ¬elen, ¬ediv, &brokenrithm, abchornpipe); + thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv); + if( abcfermata ) { +@@ -4699,7 +4699,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + abc_track_clear_tiednote(h); + p += abc_notelen(p, ¬elen, ¬ediv); + tupletr = abc_tuplet(¬elen, ¬ediv, tupletp, tupletq, tupletr); +- while( isspace(*p) ) p++; // allow spacing in broken rithm notation ++ while( isspace(static_cast(*p)) ) p++; // allow spacing in broken rithm notation + p += abc_brokenrithm(p, ¬elen, ¬ediv, &brokenrithm, abchornpipe); + thistime = notelen_notediv_to_ticks(h->speed, notelen*snotelen, notediv*snotediv); + if( abcfermata ) { +@@ -4752,7 +4752,7 @@ BOOL CSoundFile::ReadABC(const uint8_t *lpStream, DWORD dwMemLength) + abcarpeggio = 0; + break; + } +- if( isalpha(ch) && *p==':' ) { ++ if( isalpha(static_cast(ch)) && *p==':' ) { + // some unprocessed field line? + while( *p ) p++; // skip it + break; +diff --git a/src/load_mid.cpp b/src/load_mid.cpp +index fe02f5e..749b5d0 100644 +--- a/src/load_mid.cpp ++++ b/src/load_mid.cpp +@@ -1198,7 +1198,7 @@ BOOL CSoundFile::ReadMID(const BYTE *lpStream, DWORD dwMemLength) + if (h->miditracks == 0) goto ErrorCleanup; + + p = (BYTE *)getenv(ENV_MMMID_SPEED); +- if( p && isdigit(*p) && p[0] != '0' && p[1] == '\0' ) { ++ if( p && isdigit(static_cast(*p)) && p[0] != '0' && p[1] == '\0' ) { + // transform speed + t = *p - '0'; + h->speed *= t; +diff --git a/src/load_pat.cpp b/src/load_pat.cpp +index fe78731..dfa640e 100644 +--- a/src/load_pat.cpp ++++ b/src/load_pat.cpp +@@ -392,31 +392,31 @@ void pat_init_patnames(void) + _mm_fgets(mmcfg, line, PATH_MAX); + while( !_mm_feof(mmcfg) ) { + p = line; +- while ( isspace(*p) ) p ++; +- if( isdigit(p[0]) ) { ++ while ( isspace(static_cast(*p)) ) p ++; ++ if( isdigit(static_cast(p[0])) ) { + // get pat number + i = atoi(p); +- while ( isdigit(*p) ) p ++; +- while ( isspace(*p) ) p ++; ++ while ( isdigit(static_cast(*p)) ) p ++; ++ while ( isspace(static_cast(*p)) ) p ++; + // get pat file name + if( *p && i < MAXSMP && i >= 0 && *p != '#' ) { + q = isdrumset ? midipat[pat_gm_drumnr(i)-1] : midipat[i]; + pfnlen = 0; +- while( *p && !isspace(*p) && *p != '#' && pfnlen < 128 ) { ++ while( *p && !isspace(static_cast(*p)) && *p != '#' && pfnlen < 128 ) { + pfnlen ++; + *q++ = *p++; + } +- if( isblank(*p) && *(p+1) != '#' && pfnlen < 128 ) { ++ if( isblank(static_cast(*p)) && *(p+1) != '#' && pfnlen < 128 ) { + *q++ = ':'; pfnlen ++; +- while( isspace(*p) ) { +- while( isspace(*p) ) p++; ++ while( isspace(static_cast(*p)) ) { ++ while( isspace(static_cast(*p)) ) p++; + if ( *p == '#' ) { // comment + +- } else while( *p && !isspace(*p) && pfnlen < 128 ) { ++ } else while( *p && !isspace(static_cast(*p)) && pfnlen < 128 ) { + pfnlen ++; + *q++ = *p++; + } +- if( isspace(*p) ) { *q++ = ' '; pfnlen++; } ++ if( isspace(static_cast(*p)) ) { *q++ = ' '; pfnlen++; } + } + } + *q++ = '\0'; +@@ -429,11 +429,11 @@ void pat_init_patnames(void) + } + else if( !strncmp(p,"dir",3) ) { + p += 3; +- while ( isspace(*p) ) p ++; ++ while ( isspace(static_cast(*p)) ) p ++; + q = p + strlen(p); + if(q > p) { + --q; +- while ( q > p && isspace(*q) ) *(q--) = 0; ++ while ( q > p && isspace(static_cast(*q)) ) *(q--) = 0; + strncpy(pathforpat, p, PATH_MAX - 1); + pathforpat[PATH_MAX - 1] = 0; + } +@@ -441,9 +441,9 @@ void pat_init_patnames(void) + else if( !strncmp(p,"source",6) && nsources < 5 ) { + q = cfgsources[nsources]; + p += 6; +- while ( isspace(*p) ) p ++; ++ while ( isspace(static_cast(*p)) ) p ++; + pfnlen = 0; +- while ( *p && *p != '#' && !isspace(*p) && pfnlen < 128 ) { ++ while ( *p && *p != '#' && !isspace(static_cast(*p)) && pfnlen < 128 ) { + pfnlen ++; + *q++ = *p++; + } +@@ -857,7 +857,7 @@ static void PAT_ReadPatterns(MODCOMMAND *pattern[], WORD psize[], PATHANDLE *h, + i = tt2 - 16 * ((h->samples - 1 - ch) & 3); + if( tt1 < i ) { + t = t % 64; +- if( isalpha(tune[t]) ) { ++ if( isalpha(static_cast(tune[t])) ) { + n = pat_modnote(pat_note(tune[t])); + ins = ch + 1; + vol = 40; +-- +2.37.2 + diff --git a/board/opendingux/patches/libmodplug/0002-Fix-wformat-overflow-in-ABC_Init.patch b/board/opendingux/patches/libmodplug/0002-Fix-wformat-overflow-in-ABC_Init.patch new file mode 100644 index 000000000000..1197d94d6ea8 --- /dev/null +++ b/board/opendingux/patches/libmodplug/0002-Fix-wformat-overflow-in-ABC_Init.patch @@ -0,0 +1,43 @@ +From af012f4f1a0c4892c0dfeaab96cbbcb353251a2d Mon Sep 17 00:00:00 2001 +From: Gleb Mazovetskiy +Date: Wed, 21 Dec 2022 11:46:41 +0000 +Subject: [PATCH 2/4] Fix -wformat-overflow in ABC_Init +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes the following warnings + +``` +load_abc.cpp:2374:42: warning: ‘%ld’ directive writing between 1 and 20 bytes into a region of size 18 [-Wformat-overflow=] + 2374 | sprintf(buf,"%s=-%ld",ABC_ENV_NORANDOMPICK,retval->pickrandom+2); + | ^~~ +load_abc.cpp:2374:37: note: directive argument in the range [-9223372036854775806, 9223372036854775807] + 2374 | sprintf(buf,"%s=-%ld",ABC_ENV_NORANDOMPICK,retval->pickrandom+2); + | ^~~~~~~~~ +load_abc.cpp:2374:32: note: ‘sprintf’ output between 24 and 43 bytes into a destination of size 40 + 2374 | sprintf(buf,"%s=-%ld",ABC_ENV_NORANDOMPICK,retval->pickrandom+2); + | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +Signed-off-by: Gleb Mazovetskiy +--- + src/load_abc.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/load_abc.cpp b/src/load_abc.cpp +index 8444bd8..93acb13 100644 +--- a/src/load_abc.cpp ++++ b/src/load_abc.cpp +@@ -2351,7 +2351,7 @@ BOOL CSoundFile::TestABC(const BYTE *lpStream, DWORD dwMemLength) + // ===================================================================================== + static ABCHANDLE *ABC_Init(void) + { +- static char buf[40]; ++ static char buf[43]; + ABCHANDLE *retval; + char *p; + retval = (ABCHANDLE *)calloc(1,sizeof(ABCHANDLE)); +-- +2.37.2 + diff --git a/board/opendingux/patches/libmodplug/0003-avoid-unaligned-loads-stores.patch b/board/opendingux/patches/libmodplug/0003-avoid-unaligned-loads-stores.patch new file mode 100644 index 000000000000..4e899f462bf4 --- /dev/null +++ b/board/opendingux/patches/libmodplug/0003-avoid-unaligned-loads-stores.patch @@ -0,0 +1,1125 @@ +From 7bdfbba6f2cd6bbedeead73a6085c0b28a606fa5 Mon Sep 17 00:00:00 2001 +From: Ozkan Sezer +Date: Fri, 24 Feb 2023 21:56:20 +0300 +Subject: [PATCH 3/4] avoid unaligned loads / stores + +Signed-off-by: Gleb Mazovetskiy +--- + src/libmodplug/sndfile.h | 21 ++++- + src/load_amf.cpp | 18 ++-- + src/load_ams.cpp | 12 +-- + src/load_dmf.cpp | 6 +- + src/load_it.cpp | 30 +++---- + src/load_med.cpp | 6 +- + src/load_mod.cpp | 2 +- + src/load_mt2.cpp | 18 ++-- + src/load_psm.cpp | 10 +-- + src/load_s3m.cpp | 2 +- + src/load_umx.cpp | 35 ++++---- + src/load_wav.cpp | 6 +- + src/load_xm.cpp | 26 +++--- + src/mmcmp.cpp | 182 +++++++++++++++++---------------------- + src/sndfile.cpp | 69 ++++++++------- + 15 files changed, 218 insertions(+), 225 deletions(-) + +diff --git a/src/libmodplug/sndfile.h b/src/libmodplug/sndfile.h +index 1888500..7456b4d 100644 +--- a/src/libmodplug/sndfile.h ++++ b/src/libmodplug/sndfile.h +@@ -804,9 +804,6 @@ public: + }; + + +-// inline DWORD BigEndian(DWORD x) { return ((x & 0xFF) << 24) | ((x & 0xFF00) << 8) | ((x & 0xFF0000) >> 8) | ((x & 0xFF000000) >> 24); } +-// inline WORD BigEndianW(WORD x) { return (WORD)(((x >> 8) & 0xFF) | ((x << 8) & 0xFF00)); } +- + + ////////////////////////////////////////////////////////// + // WAVE format information +@@ -958,6 +955,24 @@ int _muldiv(long a, long b, long c); + int _muldivr(long a, long b, long c); + + ++// Functions to read 16 and 32 bits endian-specific data and return in native format: ++ ++inline WORD READ_LE16(LPCBYTE b) { ++ return (WORD)b[0] | ((WORD)b[1] << 8); ++} ++ ++inline WORD READ_BE16(LPCBYTE b) { ++ return (WORD)b[1] | ((WORD)b[0] << 8); ++} ++ ++inline DWORD READ_LE32(LPCBYTE b) { ++ return (DWORD)b[0] | ((DWORD)b[1] << 8) | ((DWORD)b[2] << 16) | ((DWORD)b[3] << 24); ++} ++ ++inline DWORD READ_BE32(LPCBYTE b) { ++ return (DWORD)b[3] | ((DWORD)b[2] << 8) | ((DWORD)b[1] << 16) | ((DWORD)b[0] << 24); ++} ++ + // Byte swapping functions from the GNU C Library and libsdl + + /* Swap bytes in 16 bit value. */ +diff --git a/src/load_amf.cpp b/src/load_amf.cpp +index 89876af..2512c29 100644 +--- a/src/load_amf.cpp ++++ b/src/load_amf.cpp +@@ -56,7 +56,7 @@ VOID AMF_Unpack(MODCOMMAND *pPat, const BYTE *pTrack, UINT nRows, UINT nChannels + //------------------------------------------------------------------------------- + { + UINT lastinstr = 0; +- UINT nTrkSize = bswapLE16(*(USHORT *)pTrack); ++ UINT nTrkSize = READ_LE16(pTrack); + nTrkSize += (UINT)pTrack[2] << 16; + pTrack += 3; + while (nTrkSize--) +@@ -203,9 +203,9 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength) + psmp->nGlobalVol = 64; + if (psmp->nVolume > 0x40) psmp->nVolume = 0x40; + psmp->nVolume <<= 2; +- psmp->nLength = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+25))); +- psmp->nLoopStart = bswapLE32(*((LPDWORD)(lpStream+dwMemPos+29))); +- psmp->nLoopEnd = psmp->nLoopStart + bswapLE32(*((LPDWORD)(lpStream+dwMemPos+33))); ++ psmp->nLength = READ_LE32(lpStream+dwMemPos+25); ++ psmp->nLoopStart = READ_LE32(lpStream+dwMemPos+29); ++ psmp->nLoopEnd = psmp->nLoopStart + READ_LE32(lpStream+dwMemPos+33); + if ((psmp->nLoopEnd > psmp->nLoopStart) && (psmp->nLoopEnd <= psmp->nLength)) + { + psmp->uFlags = CHN_LOOP; +@@ -319,7 +319,7 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength) + if (pfh->version >= 14) + { + if (dwMemPos + m_nChannels * sizeof(USHORT) + 2 > dwMemLength) return FALSE; +- PatternSize[iOrd] = bswapLE16(*(USHORT *)(lpStream+dwMemPos)); ++ PatternSize[iOrd] = READ_LE16(lpStream+dwMemPos); + dwMemPos += 2; + } else + { +@@ -348,12 +348,12 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength) + pins->nVolume = psh->volume * 4; + if (pfh->version >= 11) + { +- pins->nLoopStart = bswapLE32(*(DWORD *)(lpStream+dwMemPos)); +- pins->nLoopEnd = bswapLE32(*(DWORD *)(lpStream+dwMemPos+4)); ++ pins->nLoopStart = READ_LE32(lpStream+dwMemPos); ++ pins->nLoopEnd = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + } else + { +- pins->nLoopStart = bswapLE16(*(WORD *)(lpStream+dwMemPos)); ++ pins->nLoopStart = READ_LE16(lpStream+dwMemPos); + pins->nLoopEnd = pins->nLength; + dwMemPos += 2; + } +@@ -383,7 +383,7 @@ BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength) + memset(pTrackData, 0, sizeof(BYTE *) * realtrackcnt); + for (UINT iTrack=0; iTrack dwMemLength) return TRUE; +- tmp = *((WORD *)(lpStream+dwMemPos)); ++ tmp = READ_LE16(lpStream+dwMemPos); + dwMemPos += 2; + if (tmp >= dwMemLength || dwMemPos > dwMemLength - tmp) return TRUE; + if (tmp) +@@ -133,14 +133,14 @@ BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) + if (2*pfh->orders >= dwMemLength || dwMemPos > dwMemLength - 2*pfh->orders) return TRUE; + for (UINT iOrd=0; iOrdorders; iOrd++, dwMemPos += 2) + { +- UINT n = *((WORD *)(lpStream+dwMemPos)); ++ UINT n = READ_LE16(lpStream+dwMemPos); + Order[iOrd] = (BYTE)n; + } + // Read Patterns + for (UINT iPat=0; iPatpatterns; iPat++) + { + if (dwMemPos + 4 >= dwMemLength) return TRUE; +- UINT len = *((DWORD *)(lpStream + dwMemPos)); ++ UINT len = READ_LE32(lpStream + dwMemPos); + dwMemPos += 4; + if ((len >= dwMemLength) || (dwMemPos > dwMemLength - len)) return TRUE; + PatternSize[iPat] = 64; +@@ -466,7 +466,7 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) + if (dwMemPos + chnnamlen + 256 >= dwMemLength) return TRUE; + } + // packed comments (ignored) +- UINT songtextlen = *((LPDWORD)(lpStream+dwMemPos)); ++ UINT songtextlen = READ_LE32(lpStream+dwMemPos); + dwMemPos += songtextlen; + if (dwMemPos + 256 >= dwMemLength) return TRUE; + } +@@ -487,7 +487,7 @@ BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) + for (UINT ipat=0; ipatpatterns; ipat++) + { + if (dwMemPos+8 >= dwMemLength) return TRUE; +- UINT packedlen = *((LPDWORD)(lpStream+dwMemPos)); ++ UINT packedlen = READ_LE32(lpStream+dwMemPos); + UINT numrows = 1 + (UINT)(lpStream[dwMemPos+4]); + //UINT patchn = 1 + (UINT)(lpStream[dwMemPos+5] & 0x1F); + //UINT patcmds = 1 + (UINT)(lpStream[dwMemPos+5] >> 5); +@@ -579,7 +579,7 @@ static BOOL AMSUnpackCheck(const BYTE *lpStream, DWORD dwMemLength, MODINSTRUMEN + // ----------------------------------------------------------------------------------- + { + if (dwMemLength < 9) return FALSE; +- DWORD packedbytes = *((DWORD *)(lpStream + 4)); ++ DWORD packedbytes = READ_LE32(lpStream + 4); + + DWORD samplebytes = ins->nLength; + if (samplebytes > MAX_SAMPLE_LENGTH) samplebytes = MAX_SAMPLE_LENGTH; +diff --git a/src/load_dmf.cpp b/src/load_dmf.cpp +index e4fc72c..d4331c5 100644 +--- a/src/load_dmf.cpp ++++ b/src/load_dmf.cpp +@@ -106,7 +106,7 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength) + #endif + while (dwMemPos < dwMemLength - 7) + { +- DWORD id = *((LPDWORD)(lpStream+dwMemPos)); ++ DWORD id = READ_LE32(lpStream+dwMemPos); + + switch(id) + { +@@ -456,10 +456,10 @@ BOOL CSoundFile::ReadDMF(const BYTE *lpStream, DWORD dwMemLength) + #endif + break; + } +- pksize = *((LPDWORD)(lpStream+dwPos)); ++ pksize = READ_LE32(lpStream+dwPos); + #ifdef DMFLOG + Log("sample %d: pos=0x%X pksize=%d ", iSmp, dwPos, pksize); +- Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], *((LPDWORD)(lpStream+dwPos+4))); ++ Log("len=%d flags=0x%X [%08X]\n", Ins[iSmp].nLength, smplflags[ismpd], READ_LE32(lpStream+dwPos+4)); + #endif + dwPos += 4; + if (pksize > dwMemLength - dwPos) +diff --git a/src/load_it.cpp b/src/load_it.cpp +index 45fa8e4..e26fb8e 100644 +--- a/src/load_it.cpp ++++ b/src/load_it.cpp +@@ -259,7 +259,7 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) + // Reading IT Extra Info + if (dwMemPos + 2 < dwMemLength) + { +- UINT nflt = bswapLE16(*((WORD *)(lpStream + dwMemPos))); ++ UINT nflt = READ_LE16(lpStream + dwMemPos); + dwMemPos += 2; + if (dwMemPos + nflt * 8 < dwMemLength) dwMemPos += nflt * 8; + } +@@ -273,9 +273,9 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Read pattern names: "PNAM" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e50)) + { +- UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if ((dwMemPos + len <= dwMemLength) && (len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME)) + { +@@ -291,9 +291,9 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) + // 4-channels minimum + m_nChannels = 4; + // Read channel names: "CNAM" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e43)) + { +- UINT len = bswapLE32(*((DWORD *)(lpStream+dwMemPos+4))); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if ((dwMemPos + len <= dwMemLength) && (len <= 64*MAX_CHANNELNAME)) + { +@@ -319,8 +319,8 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) + { + memset(chnmask, 0, sizeof(chnmask)); + if ((!patpos[patchk]) || ((DWORD)patpos[patchk] >= dwMemLength - 4)) continue; +- UINT len = bswapLE16(*((WORD *)(lpStream+patpos[patchk]))); +- UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[patchk]+2))); ++ UINT len = READ_LE16(lpStream+patpos[patchk]); ++ UINT rows = READ_LE16(lpStream+patpos[patchk]+2); + if ((rows < 4) || (rows > 256)) continue; + if (8+len > dwMemLength || patpos[patchk] > dwMemLength - (8+len)) continue; + UINT i = 0; +@@ -451,8 +451,8 @@ BOOL CSoundFile::ReadIT(const BYTE *lpStream, DWORD dwMemLength) + continue; + } + +- UINT len = bswapLE16(*((WORD *)(lpStream+patpos[npat]))); +- UINT rows = bswapLE16(*((WORD *)(lpStream+patpos[npat]+2))); ++ UINT len = READ_LE16(lpStream+patpos[npat]); ++ UINT rows = READ_LE16(lpStream+patpos[npat]+2); + if ((rows < 4) || (rows > 256)) continue; + if (8+len > dwMemLength || patpos[npat] > dwMemLength - (8+len)) continue; + PatternSize[npat] = rows; +@@ -1233,7 +1233,7 @@ DWORD ITUnpack8Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD dw + if (!wCount) + { + wCount = 0x8000; +- // wHdr = bswapLE16(*((LPWORD)pSrc)); ++ // wHdr = READ_LE16(pSrc); + pSrc += 2; + bLeft = 9; + bTemp = bTemp2 = 0; +@@ -1320,7 +1320,7 @@ DWORD ITUnpack16Bit(signed char *pSample, DWORD dwLen, LPBYTE lpMemFile, DWORD d + if (!wCount) + { + wCount = 0x4000; +- // wHdr = bswapLE16(*((LPWORD)pSrc)); ++ // wHdr = READ_LE16(pSrc); + pSrc += 2; + bLeft = 17; + wTemp = wTemp2 = 0; +@@ -1482,13 +1482,13 @@ UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) + DWORD nPluginSize; + UINT nPlugin; + +- nPluginSize = bswapLE32(*(DWORD *)(p+nPos+4)); ++ nPluginSize = READ_LE32(p+nPos+4); + if (nPluginSize > nLen-nPos-8) break;; +- if ((bswapLE32(*(DWORD *)(p+nPos))) == 0x58464843) ++ if (READ_LE32(p+nPos) == 0x58464843) + { + for (UINT ch=0; ch<64; ch++) if (ch*4 < nPluginSize) + { +- ChnSettings[ch].nMixPlugin = bswapLE32(*(DWORD *)(p+nPos+8+ch*4)); ++ ChnSettings[ch].nMixPlugin = READ_LE32(p+nPos+8+ch*4); + } + } else + { +@@ -1500,7 +1500,7 @@ UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) + nPlugin = (p[nPos+2]-'0')*10 + (p[nPos+3]-'0'); + if ((nPlugin < MAX_MIXPLUGINS) && (nPluginSize >= sizeof(SNDMIXPLUGININFO)+4)) + { +- DWORD dwExtra = bswapLE32(*(DWORD *)(p+nPos+8+sizeof(SNDMIXPLUGININFO))); ++ DWORD dwExtra = READ_LE32(p+nPos+8+sizeof(SNDMIXPLUGININFO)); + m_MixPlugins[nPlugin].Info = *(const SNDMIXPLUGININFO *)(p+nPos+8); + m_MixPlugins[nPlugin].Info.dwPluginId1 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId1); + m_MixPlugins[nPlugin].Info.dwPluginId2 = bswapLE32(m_MixPlugins[nPlugin].Info.dwPluginId2); +diff --git a/src/load_med.cpp b/src/load_med.cpp +index e5b3076..9069415 100644 +--- a/src/load_med.cpp ++++ b/src/load_med.cpp +@@ -755,9 +755,9 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + { + while (trktagofs < dwMemLength - 8) + { +- DWORD ntag = bswapBE32(*(DWORD *)(lpStream + trktagofs)); ++ DWORD ntag = READ_BE32(lpStream + trktagofs); + if (ntag == MMDTAG_END) break; +- DWORD tagdata = bswapBE32(*(DWORD *)(lpStream + trktagofs + 4)); ++ DWORD tagdata = READ_BE32(lpStream + trktagofs + 4); + switch(ntag) + { + case MMDTAG_TRK_NAMELEN: trknamelen = tagdata; break; +@@ -894,7 +894,7 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + DWORD cmdexttable = bswapBE32(pbi->cmdexttable); + if (cmdexttable < dwMemLength - 4) + { +- cmdexttable = bswapBE32(*(DWORD *)(lpStream + cmdexttable)); ++ cmdexttable = READ_BE32(lpStream + cmdexttable); + if ((cmdexttable) && (cmdexttable <= dwMemLength - lines*tracks)) + { + pcmdext = (BYTE *)(lpStream + cmdexttable); +diff --git a/src/load_mod.cpp b/src/load_mod.cpp +index 4b64b23..8a5b6f1 100644 +--- a/src/load_mod.cpp ++++ b/src/load_mod.cpp +@@ -187,7 +187,7 @@ static BOOL IsValidName(LPCSTR s, int length, CHAR minChar) + + static BOOL IsMagic(LPCSTR s1, LPCSTR s2) + { +- return ((*(DWORD *)s1) == (*(DWORD *)s2)) ? TRUE : FALSE; ++ return memcmp(s1, s2, 4) ? FALSE : TRUE; + } + + BOOL CSoundFile::ReadMod(const BYTE *lpStream, DWORD dwMemLength) +diff --git a/src/load_mt2.cpp b/src/load_mt2.cpp +index a4c2aab..8f26c66 100644 +--- a/src/load_mt2.cpp ++++ b/src/load_mt2.cpp +@@ -225,7 +225,7 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + m_szNames[0][31] = 0; + dwMemPos = sizeof(MT2FILEHEADER); + if (dwMemPos+2 > dwMemLength) return TRUE; +- nDrumDataLen = *(WORD *)(lpStream + dwMemPos); ++ nDrumDataLen = READ_LE16(lpStream + dwMemPos); + dwDrumDataPos = dwMemPos + 2; + if (nDrumDataLen >= 2) pdd = (MT2DRUMSDATA *)(lpStream+dwDrumDataPos); + dwMemPos += 2 + nDrumDataLen; +@@ -236,9 +236,9 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + Log("Drum Data: %d bytes @%04X\n", nDrumDataLen, dwDrumDataPos); + #endif + if (dwMemPos >= dwMemLength-12) return TRUE; +- if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4; +- if (!*(DWORD *)(lpStream+dwMemPos)) dwMemPos += 4; +- nExtraDataLen = *(DWORD *)(lpStream+dwMemPos); ++ if (!READ_LE32(lpStream+dwMemPos)) dwMemPos += 4; ++ if (!READ_LE32(lpStream+dwMemPos)) dwMemPos += 4; ++ nExtraDataLen = READ_LE32(lpStream+dwMemPos); + dwExtraDataPos = dwMemPos + 4; + dwMemPos += 4; + #ifdef MT2DEBUG +@@ -247,8 +247,8 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + if (dwMemPos + nExtraDataLen >= dwMemLength) return TRUE; + while (dwMemPos+8 < dwExtraDataPos + nExtraDataLen) + { +- DWORD dwId = *(DWORD *)(lpStream+dwMemPos); +- DWORD dwLen = *(DWORD *)(lpStream+dwMemPos+4); ++ DWORD dwId = READ_LE32(lpStream+dwMemPos); ++ DWORD dwLen = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if (dwLen >= dwMemLength || dwMemPos > dwMemLength - dwLen) return TRUE; + #ifdef MT2DEBUG +@@ -374,7 +374,7 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + for (UINT iDrm=0; iDrmwDrumPatterns; iDrm++) + { + if (dwMemPos > dwMemLength-2) return TRUE; +- UINT nLines = *(WORD *)(lpStream+dwMemPos); ++ UINT nLines = READ_LE16(lpStream+dwMemPos); + #ifdef MT2DEBUG + if (nLines != 64) Log("Drum Pattern %d: %d Lines @%04X\n", iDrm, nLines, dwMemPos); + #endif +@@ -401,7 +401,7 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + if (pma->dwFlags & (1 << iEnv)) + { + #ifdef MT2DEBUG +- UINT nPoints = *(DWORD *)(lpStream+dwMemPos); ++ UINT nPoints = READ_LE32(lpStream+dwMemPos); + Log(" Env[%d/%d] %04X @%04X: %d points\n", iAuto, nAutoCount, 1 << iEnv, dwMemPos-8, nPoints); + #endif + dwMemPos += 260; +@@ -656,7 +656,7 @@ BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) + } else + if (dwMemPos < dwMemLength-4) + { +- UINT nNameLen = *(DWORD *)(lpStream+dwMemPos); ++ UINT nNameLen = READ_LE32(lpStream+dwMemPos); + dwMemPos += nNameLen + 16; + } + if (dwMemPos >= dwMemLength-4) break; +diff --git a/src/load_psm.cpp b/src/load_psm.cpp +index d594c76..a44220d 100644 +--- a/src/load_psm.cpp ++++ b/src/load_psm.cpp +@@ -215,7 +215,7 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) + m_nChannels = pSong->channels; + // Valid song header -> convert attached chunks + { +- DWORD dwSongEnd = dwSongPos + 8 + *(DWORD *)(lpStream+dwSongPos+4); ++ DWORD dwSongEnd = dwSongPos + 8 + READ_LE32(lpStream+dwSongPos+4); + dwMemPos = dwSongPos + 8 + 11; // sizeof(PSMCHUNK)+sizeof(PSMSONGHDR) + while (dwMemPos + 8 < dwSongEnd) + { +@@ -235,10 +235,10 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) + { + BOOL bFound = FALSE; + pos -= 5; +- DWORD dwName = *(DWORD *)(pdata+pos); ++ DWORD dwName = READ_LE32(pdata+pos); + for (UINT i=0; iname; ++ DWORD dwPatName = READ_LE32(lpStream+patptrs[i]+12); + if (dwName == dwPatName) + { + bFound = TRUE; +@@ -256,10 +256,10 @@ BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) + UINT iOrd = 0; + while ((pos+5name; ++ DWORD dwPatName = READ_LE32(lpStream+patptrs[i]+12); + if (dwName == dwPatName) + { + Order[iOrd++] = i; +diff --git a/src/load_s3m.cpp b/src/load_s3m.cpp +index 9249c0e..224b384 100644 +--- a/src/load_s3m.cpp ++++ b/src/load_s3m.cpp +@@ -341,7 +341,7 @@ BOOL CSoundFile::ReadS3M(const BYTE *lpStream, DWORD dwMemLength) + { + UINT nInd = ((DWORD)ptr[nins+iPat]) << 4; + if (nInd + 0x40 > dwMemLength) continue; +- WORD len = bswapLE16(*((WORD *)(lpStream+nInd))); ++ WORD len = READ_LE16(lpStream+nInd); + nInd += 2; + PatternSize[iPat] = 64; + if ((!len) || (nInd + len > dwMemLength - 6) +diff --git a/src/load_umx.cpp b/src/load_umx.cpp +index 056c6ca..564ca98 100644 +--- a/src/load_umx.cpp ++++ b/src/load_umx.cpp +@@ -9,6 +9,7 @@ + * Retrieves the offset, size and object type directly from umx. + */ + ++#include + #include "stdafx.h" + #include "sndfile.h" + +@@ -42,8 +43,10 @@ struct upkg_hdr { + DWORD guid[4]; + LONG generation_count; + #define UPKG_HDR_SIZE 64 /* 64 bytes up until here */ +- /*struct _genhist *gen;*/ ++ struct _genhist *gen; + }; ++/* compile time assert for upkg_hdr size */ ++typedef int _check_hdrsize[2 * (offsetof(struct upkg_hdr, gen) == UPKG_HDR_SIZE) - 1]; + + #define UMUSIC_IT 0 + #define UMUSIC_S3M 1 +@@ -249,21 +252,18 @@ static int probe_umx (const BYTE *membase, LONG memlen, + return t; + } + +-static int probe_header (void *header) ++static int probe_header (struct upkg_hdr *hdr, const BYTE *src) + { +- struct upkg_hdr *hdr; +- unsigned char *p; +- DWORD *swp; +- int i; +- +- /* byte swap the header - all members are 32 bit LE values */ +- p = (unsigned char *) header; +- swp = (DWORD *) header; +- for (i = 0; i < UPKG_HDR_SIZE/4; i++, p += 4) { +- swp[i] = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); +- } ++ hdr->tag = READ_LE32(src + 0); ++ hdr->file_version = READ_LE32(src + 4); ++ hdr->pkg_flags = READ_LE32(src + 8); ++ hdr->name_count = READ_LE32(src + 12); ++ hdr->name_offset = READ_LE32(src + 16); ++ hdr->export_count = READ_LE32(src + 20); ++ hdr->export_offset = READ_LE32(src + 24); ++ hdr->import_count = READ_LE32(src + 28); ++ hdr->import_offset = READ_LE32(src + 32); + +- hdr = (struct upkg_hdr *) header; + if (hdr->tag != UPKG_HDR_TAG) { + return -1; + } +@@ -300,13 +300,12 @@ static int probe_header (void *header) + static int process_upkg (const BYTE *membase, LONG memlen, + LONG *ofs, LONG *objsize) + { +- char header[UPKG_HDR_SIZE]; ++ struct upkg_hdr header; + +- memcpy(header, membase, UPKG_HDR_SIZE); +- if (probe_header(header) < 0) ++ if (probe_header(&header, membase) < 0) + return -1; + +- return probe_umx(membase, memlen, (struct upkg_hdr *)header, ofs, objsize); ++ return probe_umx(membase, memlen, &header, ofs, objsize); + } + + BOOL CSoundFile::ReadUMX(const BYTE *lpStream, DWORD dwMemLength) +diff --git a/src/load_wav.cpp b/src/load_wav.cpp +index 48de613..8d5fe2f 100644 +--- a/src/load_wav.cpp ++++ b/src/load_wav.cpp +@@ -118,10 +118,10 @@ BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength) + { + int slsize = pfmt->bitspersample >> 3; + signed short *p = (signed short *)pins->pSample; +- signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn*slsize+slsize-2); ++ const BYTE *psrc = lpStream + dwMemPos + 8 + nChn*slsize + slsize - 2; + for (UINT i=0; i 4)) + { + int nIndex; +- value = *((short int *)psrc); ++ value = READ_LE16(psrc); + nIndex = psrc[2]; + psrc += 4; + dwBytes -= 4; +diff --git a/src/load_xm.cpp b/src/load_xm.cpp +index 4d5a493..2a398a3 100644 +--- a/src/load_xm.cpp ++++ b/src/load_xm.cpp +@@ -159,17 +159,17 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + UINT ipatmap = pattern_map[ipat]; + DWORD dwSize = 0; + WORD rows=64, packsize=0; +- dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos))); ++ dwSize = READ_LE32(lpStream+dwMemPos); + while ((dwMemPos + dwSize >= dwMemLength) || (dwSize & 0xFFFFFF00)) + { + if (dwMemPos + 4 >= dwMemLength) break; + dwMemPos++; +- dwSize = bswapLE32(*((DWORD *)(lpStream+dwMemPos))); ++ dwSize = READ_LE32(lpStream+dwMemPos); + } + if (dwMemPos + 9 > dwMemLength) return TRUE; +- rows = bswapLE16(*((WORD *)(lpStream+dwMemPos+5))); ++ rows = READ_LE16(lpStream+dwMemPos+5); + if ((!rows) || (rows > 256)) rows = 64; +- packsize = bswapLE16(*((WORD *)(lpStream+dwMemPos+7))); ++ packsize = READ_LE16(lpStream+dwMemPos+7); + if (dwMemPos + dwSize + 4 > dwMemLength) return TRUE; + dwMemPos += dwSize; + if (dwMemPos + packsize + 4 > dwMemLength) return TRUE; +@@ -268,7 +268,7 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + // Wrong offset check + while (dwMemPos + 4 < dwMemLength) + { +- DWORD d = bswapLE32(*((DWORD *)(lpStream+dwMemPos))); ++ DWORD d = READ_LE32(lpStream+dwMemPos); + if (d < 0x300) break; + dwMemPos++; + } +@@ -519,9 +519,9 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Read song comments: "TEXT" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x74786574)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x74786574)) + { +- UINT len = *((DWORD *)(lpStream+dwMemPos+4)); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if ((dwMemPos + len <= dwMemLength) && (len < 16384)) + { +@@ -535,9 +535,9 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Read midi config: "MIDI" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4944494D)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4944494D)) + { +- UINT len = *((DWORD *)(lpStream+dwMemPos+4)); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE; + if (len == sizeof(MODMIDICFG)) +@@ -547,9 +547,9 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Read pattern names: "PNAM" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e50)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e50)) + { +- UINT len = *((DWORD *)(lpStream+dwMemPos+4)); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE; + if ((len <= MAX_PATTERNS*MAX_PATTERNNAME) && (len >= MAX_PATTERNNAME)) +@@ -565,9 +565,9 @@ BOOL CSoundFile::ReadXM(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Read channel names: "CNAM" +- if ((dwMemPos + 8 < dwMemLength) && (bswapLE32(*((DWORD *)(lpStream+dwMemPos))) == 0x4d414e43)) ++ if ((dwMemPos + 8 < dwMemLength) && (READ_LE32(lpStream+dwMemPos) == 0x4d414e43)) + { +- UINT len = *((DWORD *)(lpStream+dwMemPos+4)); ++ UINT len = READ_LE32(lpStream+dwMemPos+4); + dwMemPos += 8; + if (len >= dwMemLength || dwMemPos > dwMemLength - len) return TRUE; + if (len <= MAX_BASECHANNELS*MAX_CHANNELNAME) +diff --git a/src/mmcmp.cpp b/src/mmcmp.cpp +index 98d7821..0b53107 100644 +--- a/src/mmcmp.cpp ++++ b/src/mmcmp.cpp +@@ -15,7 +15,7 @@ typedef struct MMCMPFILEHEADER + { + char id[8]; /* string 'ziRCONia' */ + WORD hdrsize; /* sizeof MMCMPHEADER */ +-} MMCMPFILEHEADER, *LPMMCMPFILEHEADER; ++} MMCMPFILEHEADER; + + typedef struct MMCMPHEADER + { +@@ -25,7 +25,7 @@ typedef struct MMCMPHEADER + DWORD blktable; + BYTE glb_comp; + BYTE fmt_comp; +-} MMCMPHEADER, *LPMMCMPHEADER; ++} MMCMPHEADER; + + typedef struct MMCMPBLOCK + { +@@ -36,13 +36,13 @@ typedef struct MMCMPBLOCK + WORD flags; + WORD tt_entries; + USHORT num_bits; +-} MMCMPBLOCK, *LPMMCMPBLOCK; ++} MMCMPBLOCK; + + typedef struct MMCMPSUBBLOCK + { + DWORD unpk_pos; + DWORD unpk_size; +-} MMCMPSUBBLOCK, *LPMMCMPSUBBLOCK; ++} MMCMPSUBBLOCK; + #pragma pack() + + /* make sure of structure sizes */ +@@ -113,34 +113,21 @@ static const UINT MMCMP16BitFetch[16] = + }; + + +-static void swap_mfh(LPMMCMPFILEHEADER fh) ++static void read_block (MMCMPBLOCK *pblk, LPCBYTE src) + { +- fh->hdrsize = bswapLE16(fh->hdrsize); ++ pblk->unpk_size = READ_LE32(src + 0); ++ pblk->pk_size = READ_LE32(src + 4); ++ pblk->xor_chk = READ_LE32(src + 8); ++ pblk->sub_blk = READ_LE16(src + 12); ++ pblk->flags = READ_LE16(src + 14); ++ pblk->tt_entries = READ_LE16(src + 16); ++ pblk->num_bits = READ_LE16(src + 18); + } + +-static void swap_mmh(LPMMCMPHEADER mh) ++static void read_subblock (MMCMPSUBBLOCK *psub, LPCBYTE src) + { +- mh->version = bswapLE16(mh->version); +- mh->nblocks = bswapLE16(mh->nblocks); +- mh->filesize = bswapLE32(mh->filesize); +- mh->blktable = bswapLE32(mh->blktable); +-} +- +-static void swap_block (LPMMCMPBLOCK blk) +-{ +- blk->unpk_size = bswapLE32(blk->unpk_size); +- blk->pk_size = bswapLE32(blk->pk_size); +- blk->xor_chk = bswapLE32(blk->xor_chk); +- blk->sub_blk = bswapLE16(blk->sub_blk); +- blk->flags = bswapLE16(blk->flags); +- blk->tt_entries = bswapLE16(blk->tt_entries); +- blk->num_bits = bswapLE16(blk->num_bits); +-} +- +-static void swap_subblock (LPMMCMPSUBBLOCK sblk) +-{ +- sblk->unpk_pos = bswapLE32(sblk->unpk_pos); +- sblk->unpk_size = bswapLE32(sblk->unpk_size); ++ psub->unpk_pos = READ_LE32(src + 0); ++ psub->unpk_size = READ_LE32(src + 4); + } + + static BOOL MMCMP_IsDstBlockValid(const MMCMPSUBBLOCK *psub, DWORD dstlen) +@@ -157,11 +144,9 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + DWORD dwMemLength; + LPCBYTE lpMemFile; + LPBYTE pBuffer,pBufEnd; +- LPMMCMPFILEHEADER pmfh; +- LPMMCMPHEADER pmmh; +- const DWORD *pblk_table; ++ LPCBYTE pblk_table; ++ DWORD nblocks, blktable; + DWORD dwFileSize; +- BYTE tmp0[32], tmp1[32]; + + if (PP20_Unpack(ppMemFile, pdwMemLength)) + { +@@ -171,99 +156,96 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + dwMemLength = *pdwMemLength; + lpMemFile = *ppMemFile; + if ((dwMemLength < 256) || (!lpMemFile)) return FALSE; +- memcpy(tmp0, lpMemFile, 24); +- pmfh = (LPMMCMPFILEHEADER)(tmp0); +- pmmh = (LPMMCMPHEADER)(tmp0+10); +- swap_mfh(pmfh); +- swap_mmh(pmmh); + +- if ((memcmp(pmfh->id,"ziRCONia",8) != 0) || (pmfh->hdrsize != 14)) ++ if (memcmp(lpMemFile,"ziRCONia",8) != 0) ++ return FALSE; ++ if (READ_LE16(lpMemFile+8) != 14) /* hdrsize */ + return FALSE; +- if ((!pmmh->nblocks) || (pmmh->filesize < 16) || (pmmh->filesize > 0x8000000) || +- (pmmh->blktable >= dwMemLength) || (pmmh->blktable + 4*pmmh->nblocks > dwMemLength)) { ++ ++ nblocks = READ_LE16(lpMemFile+12); ++ dwFileSize = READ_LE32(lpMemFile+14); ++ blktable = READ_LE32(lpMemFile+18); ++ if (!nblocks || (dwFileSize < 16) || (dwFileSize > 0x8000000) || ++ (blktable >= dwMemLength) || (blktable + 4*nblocks > dwMemLength)) { + return FALSE; + } +- dwFileSize = pmmh->filesize; ++ + if ((pBuffer = (LPBYTE)calloc(1, (dwFileSize + 31) & ~15)) == NULL) + return FALSE; + pBufEnd = pBuffer + dwFileSize; +- pblk_table = (const DWORD *)(lpMemFile+pmmh->blktable); +- for (UINT nBlock=0; nBlocknblocks; nBlock++) ++ pblk_table = lpMemFile + blktable; ++ for (UINT nBlock=0; nBlock < nblocks; nBlock++) + { +- DWORD dwMemPos = bswapLE32(pblk_table[nBlock]); ++ DWORD dwMemPos = READ_LE32(pblk_table + 4*nBlock); + DWORD dwSubPos; +- LPMMCMPBLOCK pblk; +- LPMMCMPSUBBLOCK psubblk; ++ MMCMPBLOCK blk; ++ MMCMPSUBBLOCK subblk; + + if (dwMemPos >= dwMemLength - 20) + goto err; +- memcpy(tmp1,lpMemFile+dwMemPos,28); +- pblk = (LPMMCMPBLOCK)(tmp1); +- psubblk = (LPMMCMPSUBBLOCK)(tmp1+20); +- swap_block(pblk); +- swap_subblock(psubblk); ++ read_block(&blk, lpMemFile + dwMemPos); ++ read_subblock(&subblk, lpMemFile + dwMemPos + 20); + +- if (!pblk->unpk_size || !pblk->pk_size || !pblk->sub_blk) ++ if (!blk.unpk_size || !blk.pk_size || !blk.sub_blk) + goto err; +- if (pblk->pk_size <= pblk->tt_entries) ++ if (blk.pk_size <= blk.tt_entries) + goto err; +- if (pblk->sub_blk*8 >= dwMemLength - dwMemPos - 20) ++ if (blk.sub_blk*8 >= dwMemLength - dwMemPos - 20) + goto err; +- if (pblk->flags & MMCMP_COMP) { +- if (pblk->flags & MMCMP_16BIT) { +- if (pblk->num_bits >= 16) ++ if (blk.flags & MMCMP_COMP) { ++ if (blk.flags & MMCMP_16BIT) { ++ if (blk.num_bits >= 16) + goto err; + } + else { +- if (pblk->num_bits >= 8) ++ if (blk.num_bits >= 8) + goto err; + } + } + + dwSubPos = dwMemPos + 20; +- dwMemPos += 20 + pblk->sub_blk*8; ++ dwMemPos += 20 + blk.sub_blk*8; + #ifdef MMCMP_LOG +- Log("block %d: flags=%04X sub_blocks=%d", nBlock, (UINT)pblk->flags, (UINT)pblk->sub_blk); +- Log(" pksize=%d unpksize=%d", pblk->pk_size, pblk->unpk_size); +- Log(" tt_entries=%d num_bits=%d\n", pblk->tt_entries, pblk->num_bits); ++ Log("block %d: flags=%04X sub_blocks=%d", nBlock, (UINT)blk.flags, (UINT)blk.sub_blk); ++ Log(" pksize=%d unpksize=%d", blk.pk_size, blk.unpk_size); ++ Log(" tt_entries=%d num_bits=%d\n", blk.tt_entries, blk.num_bits); + #endif +- if (!(pblk->flags & MMCMP_COMP)) ++ if (!(blk.flags & MMCMP_COMP)) + { /* Data is not packed */ + UINT i=0; + while (1) { + #ifdef MMCMP_LOG +- Log(" Unpacked sub-block %d: offset %d, size=%d\n", i, psubblk->unpk_pos, psubblk->unpk_size); ++ Log(" Unpacked sub-block %d: offset %d, size=%d\n", i, subblk.unpk_pos, subblk.unpk_size); + #endif +- if (!MMCMP_IsDstBlockValid(psubblk, dwFileSize)) ++ if (!MMCMP_IsDstBlockValid(&subblk, dwFileSize)) + goto err; +- memcpy(pBuffer+psubblk->unpk_pos, lpMemFile+dwMemPos, psubblk->unpk_size); +- dwMemPos += psubblk->unpk_size; +- if (++i == pblk->sub_blk) break; +- memcpy(tmp1+20,lpMemFile+dwSubPos+i*8,8); +- swap_subblock(psubblk); ++ memcpy(pBuffer+subblk.unpk_pos, lpMemFile+dwMemPos, subblk.unpk_size); ++ dwMemPos += subblk.unpk_size; ++ if (++i == blk.sub_blk) break; ++ read_subblock(&subblk, lpMemFile + dwSubPos + i*8); + } + } +- else if (pblk->flags & MMCMP_16BIT) ++ else if (blk.flags & MMCMP_16BIT) + { /* Data is 16-bit packed */ + MMCMPBITBUFFER bb; +- LPBYTE pDest = pBuffer + psubblk->unpk_pos; +- DWORD dwSize = psubblk->unpk_size; ++ LPBYTE pDest = pBuffer + subblk.unpk_pos; ++ DWORD dwSize = subblk.unpk_size; + DWORD dwPos = 0; +- UINT numbits = pblk->num_bits; +- UINT subblk = 0, oldval = 0; ++ UINT numbits = blk.num_bits; ++ UINT nsubblk = 0, oldval = 0; + + #ifdef MMCMP_LOG +- Log(" 16-bit block: pos=%d size=%d ", psubblk->unpk_pos, psubblk->unpk_size); ++ Log(" 16-bit block: pos=%d size=%d ", subblk.unpk_pos, subblk.unpk_size); + if (pblk->flags & MMCMP_DELTA) Log("DELTA "); + if (pblk->flags & MMCMP_ABS16) Log("ABS16 "); + Log("\n"); + #endif +- if (!MMCMP_IsDstBlockValid(psubblk, dwFileSize)) ++ if (!MMCMP_IsDstBlockValid(&subblk, dwFileSize)) + goto err; + bb.bitcount = 0; + bb.bitbuffer = 0; +- bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries; +- bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size; ++ bb.pSrc = lpMemFile+dwMemPos+blk.tt_entries; ++ bb.pEnd = lpMemFile+dwMemPos+blk.pk_size; + while (1) + { + UINT newval = 0x10000; +@@ -294,12 +276,12 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + if (newval < 0x10000) + { + newval = (newval & 1) ? (UINT)(-(LONG)((newval+1) >> 1)) : (UINT)(newval >> 1); +- if (pblk->flags & MMCMP_DELTA) ++ if (blk.flags & MMCMP_DELTA) + { + newval += oldval; + oldval = newval; + } else +- if (!(pblk->flags & MMCMP_ABS16)) ++ if (!(blk.flags & MMCMP_ABS16)) + { + newval ^= 0x8000; + } +@@ -310,33 +292,32 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + } + if (dwPos >= dwSize) + { +- if (++subblk == pblk->sub_blk) break; ++ if (++nsubblk == blk.sub_blk) break; + dwPos = 0; +- memcpy(tmp1+20,lpMemFile+dwSubPos+subblk*8,8); +- swap_subblock(psubblk); +- if (!MMCMP_IsDstBlockValid(psubblk, dwFileSize)) ++ read_subblock(&subblk, lpMemFile + dwSubPos + nsubblk*8); ++ if (!MMCMP_IsDstBlockValid(&subblk, dwFileSize)) + goto err; +- dwSize = psubblk->unpk_size; +- pDest = pBuffer + psubblk->unpk_pos; ++ dwSize = subblk.unpk_size; ++ pDest = pBuffer + subblk.unpk_pos; + } + } + } + else + { /* Data is 8-bit packed */ + MMCMPBITBUFFER bb; +- LPBYTE pDest = pBuffer + psubblk->unpk_pos; +- DWORD dwSize = psubblk->unpk_size; ++ LPBYTE pDest = pBuffer + subblk.unpk_pos; ++ DWORD dwSize = subblk.unpk_size; + DWORD dwPos = 0; +- UINT numbits = pblk->num_bits; +- UINT subblk = 0, oldval = 0; ++ UINT numbits = blk.num_bits; ++ UINT nsubblk = 0, oldval = 0; + LPCBYTE ptable = lpMemFile+dwMemPos; + +- if (!MMCMP_IsDstBlockValid(psubblk, dwFileSize)) ++ if (!MMCMP_IsDstBlockValid(&subblk, dwFileSize)) + goto err; + bb.bitcount = 0; + bb.bitbuffer = 0; +- bb.pSrc = lpMemFile+dwMemPos+pblk->tt_entries; +- bb.pEnd = lpMemFile+dwMemPos+pblk->pk_size; ++ bb.pSrc = lpMemFile+dwMemPos+blk.tt_entries; ++ bb.pEnd = lpMemFile+dwMemPos+blk.pk_size; + while (1) + { + UINT newval = 0x100; +@@ -367,7 +348,7 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + if (newval < 0x100) + { + int n = ptable[newval]; +- if (pblk->flags & MMCMP_DELTA) ++ if (blk.flags & MMCMP_DELTA) + { + n += oldval; + oldval = n; +@@ -376,14 +357,13 @@ BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength) + } + if (dwPos >= dwSize) + { +- if (++subblk == pblk->sub_blk) break; ++ if (++nsubblk == blk.sub_blk) break; + dwPos = 0; +- memcpy(tmp1+20,lpMemFile+dwSubPos+subblk*8,8); +- swap_subblock(psubblk); +- if (!MMCMP_IsDstBlockValid(psubblk, dwFileSize)) ++ read_subblock(&subblk, lpMemFile + dwSubPos + nsubblk*8); ++ if (!MMCMP_IsDstBlockValid(&subblk, dwFileSize)) + goto err; +- dwSize = psubblk->unpk_size; +- pDest = pBuffer + psubblk->unpk_pos; ++ dwSize = subblk.unpk_size; ++ pDest = pBuffer + subblk.unpk_pos; + } + } + } +diff --git a/src/sndfile.cpp b/src/sndfile.cpp +index 24550de..b1734d8 100644 +--- a/src/sndfile.cpp ++++ b/src/sndfile.cpp +@@ -1091,8 +1091,10 @@ UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMa + // 4 = 16-bit ADPCM data with linear table + // 5 = signed 16-bit PCM data + // 6 = unsigned 16-bit PCM data +- +- ++// ++// Does unaligned WORD/DWORD stores to pIns->pSample with the ++// assumption that malloc() returns aligned memory already. ++// + UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) + //------------------------------------------------------------------------------ + { +@@ -1176,11 +1178,11 @@ UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, + len = pIns->nLength * 2; + if (len > dwMemLength) break; + int16_t *pSample = (int16_t *)pIns->pSample; +- int16_t *p = (int16_t *)lpMemFile; ++ LPCBYTE p = (LPCBYTE)lpMemFile; + int delta16 = 0; +- for (UINT j=0; j dwMemLength) len = dwMemLength & ~1; + if (len > 1) + { +- signed char *pSample = (signed char *)pIns->pSample; +- signed char *pSrc = (signed char *)lpMemFile; +- for (UINT j=0; jpSample; ++ LPCBYTE pSrc = (LPCBYTE)lpMemFile; ++ for (UINT j=0; jnLength * 2; + if (len > dwMemLength) break; + int16_t *pSample = (int16_t *)pIns->pSample; +- int16_t *pSrc = (int16_t *)lpMemFile; +- for (UINT j=0; jnLength * 2; + if (len*2 <= dwMemLength) + { +- signed char *pSample = (signed char *)pIns->pSample; +- signed char *pSrc = (signed char *)lpMemFile; +- for (UINT j=0; jpSample; ++ LPCBYTE pSrc = (LPCBYTE)lpMemFile; ++ for (UINT j=0; jnLength; +- int16_t *psrc = (int16_t *)lpMemFile; ++ LPCBYTE psrc0 = (LPCBYTE)lpMemFile; ++ LPCBYTE psrc1 = (LPCBYTE)lpMemFile + len*2; + int16_t *pSample = (int16_t *)pIns->pSample; + if (len*4 > dwMemLength) break; + for (UINT j=0; jnLength; + if (len*4 > dwMemLength) len = dwMemLength >> 2; +- int16_t *psrc = (int16_t *)lpMemFile; ++ LPCBYTE psrc = (LPCBYTE)lpMemFile; + int16_t *pSample = (int16_t *)pIns->pSample; + for (UINT j=0; j 9) + { + const char *psrc = lpMemFile; +- char packcharacter = lpMemFile[8], *pdest = (char *)pIns->pSample; +- UINT smplen = bswapLE32(*((LPDWORD)(lpMemFile+4))); ++ char *pdest = (char *)pIns->pSample; ++ char packcharacter = lpMemFile[8]; ++ UINT smplen = READ_LE32((LPCBYTE)lpMemFile + 4); + if (smplen > dwMemLength - 9) smplen = dwMemLength - 9; + len += smplen; + UINT dmax = pIns->nLength; +@@ -1419,7 +1418,7 @@ UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, + { + LPBYTE pSample = (LPBYTE)pIns->pSample; + LPBYTE ibuf = (LPBYTE)lpMemFile; +- DWORD bitbuf = bswapLE32(*((DWORD *)ibuf)); ++ DWORD bitbuf = READ_LE32(ibuf); + UINT bitnum = 32; + BYTE dlt = 0, lowbyte = 0; + LPBYTE ibufend = (LPBYTE)lpMemFile + dwMemLength - 1; +-- +2.37.2 + diff --git a/board/opendingux/patches/libmodplug/0004-load_med.cpp-avoid-unaligned-loads-stores.patch b/board/opendingux/patches/libmodplug/0004-load_med.cpp-avoid-unaligned-loads-stores.patch new file mode 100644 index 000000000000..64839645be67 --- /dev/null +++ b/board/opendingux/patches/libmodplug/0004-load_med.cpp-avoid-unaligned-loads-stores.patch @@ -0,0 +1,551 @@ +From 6ac4de6a596129002109b48493edefadc3cf071a Mon Sep 17 00:00:00 2001 +From: Ozkan Sezer +Date: Sat, 25 Feb 2023 14:56:10 +0300 +Subject: [PATCH 4/4] load_med.cpp: avoid unaligned loads / stores + +Signed-off-by: Gleb Mazovetskiy +--- + src/load_med.cpp | 279 ++++++++++++++++++++++++----------------------- + 1 file changed, 140 insertions(+), 139 deletions(-) + +diff --git a/src/load_med.cpp b/src/load_med.cpp +index 9069415..5405d06 100644 +--- a/src/load_med.cpp ++++ b/src/load_med.cpp +@@ -5,6 +5,7 @@ + * Adam Goode (endian and char fixes for PPC) + */ + ++#include + #include "stdafx.h" + #include "sndfile.h" + +@@ -266,7 +267,7 @@ typedef struct tagMMD0EXP + + + +-static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh) ++static void MedConvert(MODCOMMAND *p, BYTE flags, BYTE flags2) + //--------------------------------------------------------------- + { + UINT command = p->command; +@@ -284,7 +285,7 @@ static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh) + case 0x0A: if (param & 0xF0) param &= 0xF0; command = CMD_VOLUMESLIDE; if (!param) command = 0; break; + case 0x0B: command = CMD_POSITIONJUMP; break; + case 0x0C: command = CMD_VOLUME; +- if (pmsh->flags & MMD_FLAG_VOLHEX) ++ if (flags & MMD_FLAG_VOLHEX) + { + if (param < 0x80) + { +@@ -307,7 +308,7 @@ static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh) + // F.01 - F.F0: Set tempo/speed + if (param <= 0xF0) + { +- if (pmsh->flags & MMD_FLAG_8CHANNEL) ++ if (flags & MMD_FLAG_8CHANNEL) + { + param = (param > 10) ? 99 : bpmvals[param-1]; + } else +@@ -317,7 +318,7 @@ static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh) + command = CMD_SPEED; + } else + // Old tempo +- if (!(pmsh->flags2 & MMD_FLAG2_BPM)) ++ if (!(flags2 & MMD_FLAG2_BPM)) + { + param = _muldiv(param, 5*715909, 2*474326); + } +@@ -475,132 +476,131 @@ static void MedConvert(MODCOMMAND *p, const MMD0SONGHEADER *pmsh) + BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + //--------------------------------------------------------------- + { +- const MEDMODULEHEADER *pmmh; +- const MMD0SONGHEADER *pmsh; +- const MMD2SONGHEADER *pmsh2; +- const MMD0EXP *pmex; ++ const BYTE *pmsh, *pmex, *psample, *pdwTable; + DWORD dwBlockArr, dwSmplArr, dwExpData, wNumBlocks; +- LPDWORD pdwTable; + CHAR version; ++ BYTE flags, flags2; + UINT deftempo; + int playtransp = 0; + + if ((!lpStream) || (dwMemLength < 0x200)) return FALSE; +- pmmh = (MEDMODULEHEADER *)lpStream; +- if (((pmmh->id & 0x00FFFFFF) != 0x444D4D) || (!pmmh->song)) return FALSE; ++ + // Check for 'MMDx' +- DWORD dwSong = bswapBE32(pmmh->song); ++ if (memcmp(lpStream,"MMD",3) != 0) return FALSE; ++ DWORD dwSong = READ_BE32(lpStream + offsetof(MEDMODULEHEADER,song)); ++ if (!dwSong) return FALSE; + if ((dwSong >= dwMemLength) || (dwSong + sizeof(MMD0SONGHEADER) >= dwMemLength)) return FALSE; +- version = (signed char)((pmmh->id >> 24) & 0xFF); ++ version = lpStream[3]; + if ((version < '0') || (version > '3')) return FALSE; + #ifdef MED_LOG +- Log("\nLoading MMD%c module (flags=0x%02X)...\n", version, bswapBE32(pmmh->mmdflags)); +- Log(" modlen = %d\n", bswapBE32(pmmh->modlen)); +- Log(" song = 0x%08X\n", bswapBE32(pmmh->song)); +- Log(" psecnum = %d\n", bswapBE16(pmmh->psecnum)); +- Log(" pseq = %d\n", bswapBE16(pmmh->pseq)); +- Log(" blockarr = 0x%08X\n", bswapBE32(pmmh->blockarr)); +- Log(" mmdflags = 0x%08X\n", bswapBE32(pmmh->mmdflags)); +- Log(" smplarr = 0x%08X\n", bswapBE32(pmmh->smplarr)); +- Log(" reserved = 0x%08X\n", bswapBE32(pmmh->reserved)); +- Log(" expdata = 0x%08X\n", bswapBE32(pmmh->expdata)); +- Log(" reserved2= 0x%08X\n", bswapBE32(pmmh->reserved2)); +- Log(" pstate = %d\n", bswapBE16(pmmh->pstate)); +- Log(" pblock = %d\n", bswapBE16(pmmh->pblock)); +- Log(" pline = %d\n", bswapBE16(pmmh->pline)); +- Log(" pseqnum = %d\n", bswapBE16(pmmh->pseqnum)); +- Log(" actplayline=%d\n", bswapBE16(pmmh->actplayline)); +- Log(" counter = %d\n", pmmh->counter); +- Log(" extra_songs = %d\n", pmmh->extra_songs); ++ Log("\nLoading MMD%c module (flags=0x%02X)...\n", version, READ_BE32(lpStream+offsetof(MEDMODULEHEADER,mmdflags))); ++ Log(" modlen = %d\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,modlen))); ++ Log(" song = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,song))); ++ Log(" psecnum = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,psecnum))); ++ Log(" pseq = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,pseq))); ++ Log(" blockarr = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,blockarr))); ++ Log(" mmdflags = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,mmdflags))); ++ Log(" smplarr = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,smplarr))); ++ Log(" reserved = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,reserved))); ++ Log(" expdata = 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,expdata))); ++ Log(" reserved2= 0x%08X\n", READ_BE32(lpStream+offsetof(MEDMODULEHEADER,reserved2))); ++ Log(" pstate = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,pstate))); ++ Log(" pblock = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,pblock))); ++ Log(" pline = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,pline))); ++ Log(" pseqnum = %d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,pseqnum))); ++ Log(" actplayline=%d\n", READ_BE16(lpStream+offsetof(MEDMODULEHEADER,actplayline))); ++ Log(" counter = %d\n", *(lpStream+offsetof(MEDMODULEHEADER,counter))); ++ Log(" extra_songs = %d\n", *(lpStream+offsetof(MEDMODULEHEADER,extra_songs))); + Log("\n"); + #endif + m_nType = MOD_TYPE_MED; + m_nSongPreAmp = 0x20; +- dwBlockArr = bswapBE32(pmmh->blockarr); +- dwSmplArr = bswapBE32(pmmh->smplarr); +- dwExpData = bswapBE32(pmmh->expdata); ++ dwBlockArr = READ_BE32(lpStream + offsetof(MEDMODULEHEADER,blockarr)); ++ dwSmplArr = READ_BE32(lpStream + offsetof(MEDMODULEHEADER,smplarr)); ++ dwExpData = READ_BE32(lpStream + offsetof(MEDMODULEHEADER,expdata)); + if ((dwExpData) && (dwExpData < dwMemLength - sizeof(MMD0EXP))) +- pmex = (MMD0EXP *)(lpStream+dwExpData); ++ pmex = lpStream + dwExpData; /* MMD0EXP */ + else + pmex = NULL; +- pmsh = (MMD0SONGHEADER *)(lpStream + dwSong); +- pmsh2 = (MMD2SONGHEADER *)pmsh; ++ pmsh = lpStream + dwSong; /* MMD0SONGHEADER / MMD2SONGHEADER */ ++ flags = *(pmsh + offsetof(MMD0SONGHEADER,flags)); ++ flags2 = *(pmsh + offsetof(MMD0SONGHEADER,flags2)); + #ifdef MED_LOG + if (version < '2') + { + Log("MMD0 Header:\n"); +- Log(" numblocks = %d\n", bswapBE16(pmsh->numblocks)); +- Log(" songlen = %d\n", bswapBE16(pmsh->songlen)); ++ Log(" numblocks = %d\n", READ_BE16(pmsh + offsetof(MMD0SONGHEADER,numblocks))); ++ Log(" songlen = %d\n", READ_BE16(pmsh + offsetof(MMD0SONGHEADER,songlen))); + Log(" playseq = "); +- for (UINT idbg1=0; idbg1<16; idbg1++) Log("%2d, ", pmsh->playseq[idbg1]); ++ for (UINT idbg1=0; idbg1<16; idbg1++) Log("%2d, ", (pmsh + offsetof(MMD0SONGHEADER,playseq))[idbg1]); + Log("...\n"); +- Log(" deftempo = 0x%04X\n", bswapBE16(pmsh->deftempo)); +- Log(" playtransp = %d\n", (signed char)pmsh->playtransp); +- Log(" flags(1,2) = 0x%02X, 0x%02X\n", pmsh->flags, pmsh->flags2); +- Log(" tempo2 = %d\n", pmsh->tempo2); ++ Log(" deftempo = 0x%04X\n", READ_BE16(pmsh + offsetof(MMD0SONGHEADER,deftempo))); ++ Log(" playtransp = %d\n", (signed char) *(pmsh + offsetof(MMD0SONGHEADER,playtransp))); ++ Log(" flags(1,2) = 0x%02X, 0x%02X\n", *(pmsh + offsetof(MMD0SONGHEADER,flags)), *(pmsh + offsetof(MMD0SONGHEADER,flags2))); ++ Log(" tempo2 = %d\n", *(pmsh + offsetof(MMD0SONGHEADER,tempo2))); + Log(" trkvol = "); +- for (UINT idbg2=0; idbg2<16; idbg2++) Log("0x%02X, ", pmsh->trkvol[idbg2]); ++ for (UINT idbg2=0; idbg2<16; idbg2++) Log("0x%02X, ", (pmsh + offsetof(MMD0SONGHEADER,trkvol))[idbg2]); + Log("...\n"); +- Log(" mastervol = 0x%02X\n", pmsh->mastervol); +- Log(" numsamples = %d\n", pmsh->numsamples); ++ Log(" mastervol = 0x%02X\n", *(pmsh + offsetof(MMD0SONGHEADER,mastervol))); ++ Log(" numsamples = %d\n", *(pmsh + offsetof(MMD0SONGHEADER,numsamples))); + } else + { + Log("MMD2 Header:\n"); +- Log(" numblocks = %d\n", bswapBE16(pmsh2->numblocks)); +- Log(" numsections= %d\n", bswapBE16(pmsh2->numsections)); +- Log(" playseqptr = 0x%04X\n", bswapBE32(pmsh2->playseqtable)); +- Log(" sectionptr = 0x%04X\n", bswapBE32(pmsh2->sectiontable)); +- Log(" trackvols = 0x%04X\n", bswapBE32(pmsh2->trackvols)); +- Log(" numtracks = %d\n", bswapBE16(pmsh2->numtracks)); +- Log(" numpseqs = %d\n", bswapBE16(pmsh2->numpseqs)); +- Log(" trackpans = 0x%04X\n", bswapBE32(pmsh2->trackpans)); +- Log(" flags3 = 0x%08X\n", bswapBE32(pmsh2->flags3)); +- Log(" voladj = %d\n", bswapBE16(pmsh2->voladj)); +- Log(" channels = %d\n", bswapBE16(pmsh2->channels)); +- Log(" echotype = %d\n", pmsh2->mix_echotype); +- Log(" echodepth = %d\n", pmsh2->mix_echodepth); +- Log(" echolen = %d\n", bswapBE16(pmsh2->mix_echolen)); +- Log(" stereosep = %d\n", (signed char)pmsh2->mix_stereosep); +- Log(" deftempo = 0x%04X\n", bswapBE16(pmsh2->deftempo)); +- Log(" playtransp = %d\n", (signed char)pmsh2->playtransp); +- Log(" flags(1,2) = 0x%02X, 0x%02X\n", pmsh2->flags, pmsh2->flags2); +- Log(" tempo2 = %d\n", pmsh2->tempo2); +- Log(" mastervol = 0x%02X\n", pmsh2->mastervol); +- Log(" numsamples = %d\n", pmsh->numsamples); ++ Log(" numblocks = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numblocks))); ++ Log(" numsections= %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numsections))); ++ Log(" playseqptr = 0x%04X\n", READ_BE32(pmsh + offsetof(MMD2SONGHEADER,playseqtable))); ++ Log(" sectionptr = 0x%04X\n", READ_BE32(pmsh + offsetof(MMD2SONGHEADER,sectiontable))); ++ Log(" trackvols = 0x%04X\n", READ_BE32(pmsh + offsetof(MMD2SONGHEADER,trackvols))); ++ Log(" numtracks = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numtracks))); ++ Log(" numpseqs = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numpseqs))); ++ Log(" trackpans = 0x%04X\n", READ_BE32(pmsh + offsetof(MMD2SONGHEADER,trackpans))); ++ Log(" flags3 = 0x%08X\n", READ_BE32(pmsh + offsetof(MMD2SONGHEADER,flags3))); ++ Log(" voladj = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,voladj))); ++ Log(" channels = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,channels))); ++ Log(" echotype = %d\n", *(pmsh + offsetof(MMD2SONGHEADER,mix_echotype))); ++ Log(" echodepth = %d\n", *(pmsh + offsetof(MMD2SONGHEADER,mix_echodepth))); ++ Log(" echolen = %d\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,mix_echolen))); ++ Log(" stereosep = %d\n", (signed char) *(pmsh + offsetof(MMD2SONGHEADER,mix_stereosep))); ++ Log(" deftempo = 0x%04X\n", READ_BE16(pmsh + offsetof(MMD2SONGHEADER,deftempo))); ++ Log(" playtransp = %d\n", (signed char) *(pmsh + offsetof(MMD2SONGHEADER,playtransp))); ++ Log(" flags(1,2) = 0x%02X, 0x%02X\n", *(pmsh + offsetof(MMD2SONGHEADER,flags)), *(pmsh + offsetof(MMD2SONGHEADER,flags2))); ++ Log(" tempo2 = %d\n", *(pmsh + offsetof(MMD2SONGHEADER,tempo2))); ++ Log(" mastervol = 0x%02X\n", *(pmsh + offsetof(MMD2SONGHEADER,mastervol))); ++ Log(" numsamples = %d\n", *(pmsh + offsetof(MMD2SONGHEADER,numsamples))); + } + Log("\n"); + #endif +- wNumBlocks = bswapBE16(pmsh->numblocks); ++ wNumBlocks = READ_BE16(pmsh + offsetof(MMD0SONGHEADER,numblocks)); + m_nChannels = 4; +- m_nSamples = pmsh->numsamples; ++ m_nSamples = *(pmsh + offsetof(MMD0SONGHEADER,numsamples)); + if (m_nSamples > 63) m_nSamples = 63; + // Tempo + m_nDefaultTempo = 125; +- deftempo = bswapBE16(pmsh->deftempo); ++ deftempo = READ_BE16(pmsh + offsetof(MMD0SONGHEADER,deftempo)); + if (!deftempo) deftempo = 125; +- if (pmsh->flags2 & MMD_FLAG2_BPM) ++ if (flags2 & MMD_FLAG2_BPM) + { +- UINT tempo_tpl = (pmsh->flags2 & MMD_FLAG2_BMASK) + 1; ++ UINT tempo_tpl = (flags2 & MMD_FLAG2_BMASK) + 1; + if (!tempo_tpl) tempo_tpl = 4; + deftempo *= tempo_tpl; + deftempo /= 4; + #ifdef MED_LOG +- Log("newtempo: %3d bpm (bpm=%3d lpb=%2d)\n", deftempo, bswapBE16(pmsh->deftempo), (pmsh->flags2 & MMD_FLAG2_BMASK)+1); ++ Log("newtempo: %3d bpm (bpm=%3d lpb=%2d)\n", deftempo, READ_BE16(pmsh + offsetof(MMD0SONGHEADER,deftempo)), (flags2 & MMD_FLAG2_BMASK)+1); + #endif + } else + { +- if (pmsh->flags & MMD_FLAG_8CHANNEL && deftempo > 0 && deftempo <= 10) ++ if (flags & MMD_FLAG_8CHANNEL && deftempo > 0 && deftempo <= 10) + { + deftempo = bpmvals[deftempo-1]; + } else { + deftempo = _muldiv(deftempo, 5*715909, 2*474326); + } + #ifdef MED_LOG +- Log("oldtempo: %3d bpm (bpm=%3d)\n", deftempo, bswapBE16(pmsh->deftempo)); ++ Log("oldtempo: %3d bpm (bpm=%3d)\n", deftempo, READ_BE16(pmsh + offsetof(MMD0SONGHEADER,deftempo))); + #endif + } + // Speed +- m_nDefaultSpeed = pmsh->tempo2; ++ m_nDefaultSpeed = *(pmsh + offsetof(MMD0SONGHEADER,tempo2)); + if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; + if (deftempo < 0x21) deftempo = 0x21; + if (deftempo > 255) +@@ -614,39 +614,40 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + } + m_nDefaultTempo = deftempo; + // Reading Samples +- for (UINT iSHdr=0; iSHdrnLoopStart = bswapBE16(pmsh->sample[iSHdr].rep) << 1; +- pins->nLoopEnd = pins->nLoopStart + (bswapBE16(pmsh->sample[iSHdr].replen) << 1); +- pins->nVolume = (pmsh->sample[iSHdr].svol << 2); ++ pins->nLoopStart = READ_BE16(psample + offsetof(MMD0SAMPLE,rep)) << 1; ++ pins->nLoopEnd = pins->nLoopStart + (READ_BE16(psample + offsetof(MMD0SAMPLE,replen)) << 1); ++ pins->nVolume = *(psample + offsetof(MMD0SAMPLE,svol)) << 2; + pins->nGlobalVol = 64; + if (pins->nVolume > 256) pins->nVolume = 256; +- pins->RelativeTone = -12 * pmsh->sample[iSHdr].strans; ++ pins->RelativeTone = -12 * (signed char) *(psample + offsetof(MMD0SAMPLE,strans)); + pins->nPan = 128; + if (pins->nLoopEnd) pins->uFlags |= CHN_LOOP; + } + // Common Flags +- if (!(pmsh->flags & 0x20)) m_dwSongFlags |= SONG_FASTVOLSLIDES; ++ if (!(flags & 0x20)) m_dwSongFlags |= SONG_FASTVOLSLIDES; + // Reading play sequence + if (version < '2') + { +- UINT nbo = pmsh->songlen >> 8; ++ UINT nbo = READ_BE16(pmsh + offsetof(MMD0SONGHEADER,songlen)); + if (nbo >= MAX_ORDERS) nbo = MAX_ORDERS-1; + if (!nbo) nbo = 1; +- memcpy(Order, pmsh->playseq, nbo); +- playtransp = pmsh->playtransp; ++ memcpy(Order, pmsh + offsetof(MMD0SONGHEADER,playseq), nbo); ++ playtransp = (signed char) *(pmsh + offsetof(MMD0SONGHEADER,playtransp)); + } else + { + UINT nOrders, nSections; +- UINT nTrks = bswapBE16(pmsh2->numtracks); ++ UINT nTrks = READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numtracks)); + if ((nTrks >= 4) && (nTrks <= 32)) m_nChannels = nTrks; +- DWORD playseqtable = bswapBE32(pmsh2->playseqtable); +- UINT numplayseqs = bswapBE16(pmsh2->numpseqs); ++ DWORD playseqtable = READ_BE32(pmsh + offsetof(MMD2SONGHEADER,playseqtable)); ++ UINT numplayseqs = READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numpseqs)); + if (!numplayseqs) numplayseqs = 1; + nOrders = 0; +- nSections = bswapBE16(pmsh2->numsections); +- DWORD sectiontable = bswapBE32(pmsh2->sectiontable); ++ nSections = READ_BE16(pmsh + offsetof(MMD2SONGHEADER,numsections)); ++ DWORD sectiontable = READ_BE32(pmsh + offsetof(MMD2SONGHEADER,sectiontable)); + if ((!nSections) || (!sectiontable) || (sectiontable >= dwMemLength-2)) nSections = 1; + nOrders = 0; + for (UINT iSection=0; iSection sizeof(MMD2PLAYSEQ) && + (pseq < dwMemLength - sizeof(MMD2PLAYSEQ))) + { +- const MMD2PLAYSEQ *pmps = (MMD2PLAYSEQ *)(lpStream + pseq); +- if (!m_szNames[0][0]) memcpy(m_szNames[0], pmps->name, 31); +- UINT n = bswapBE16(pmps->length); +- if (n < (dwMemLength - (pseq + sizeof(*pmps)) + sizeof(pmps->seq)) / sizeof(pmps->seq[0])) ++ const BYTE *pmps = lpStream + pseq; /* MMD2PLAYSEQ */ ++ if (!m_szNames[0][0]) memcpy(m_szNames[0], pmps, 31); ++ UINT n = READ_BE16(pmps + offsetof(MMD2PLAYSEQ,length)); ++ if (n < (dwMemLength - (pseq + sizeof(MMD2PLAYSEQ)) + 512*sizeof(WORD)) / sizeof(WORD)) /* WORD seq[512] */ + { + for (UINT i=0; iseq[i] >> 8; ++ UINT seqval = READ_BE16(pmps + offsetof(MMD2PLAYSEQ,seq) + i*sizeof(WORD)); + if ((seqval < wNumBlocks) && (nOrders < MAX_ORDERS-1)) + { + Order[nOrders++] = seqval; +@@ -685,23 +686,23 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + } + } + } +- playtransp = pmsh2->playtransp; ++ playtransp = (signed char) *(pmsh + offsetof(MMD2SONGHEADER,playtransp)); + while (nOrders < MAX_ORDERS) Order[nOrders++] = 0xFF; + } + // Reading Expansion structure + if (pmex) + { + // Channel Split +- if ((m_nChannels == 4) && (pmsh->flags & MMD_FLAG_8CHANNEL)) ++ if ((m_nChannels == 4) && (flags & MMD_FLAG_8CHANNEL)) + { + for (UINT i8ch=0; i8ch<4; i8ch++) + { +- if (pmex->channelsplit[i8ch]) m_nChannels++; ++ if (*(pmex + offsetof(MMD0EXP,channelsplit) + i8ch)) m_nChannels++; + } + } + // Song Comments +- uint32_t annotxt = bswapBE32(pmex->annotxt); +- uint32_t annolen = bswapBE32(pmex->annolen); ++ uint32_t annotxt = READ_BE32(pmex + offsetof(MMD0EXP,annotxt)); ++ uint32_t annolen = READ_BE32(pmex + offsetof(MMD0EXP,annolen)); + if ((annotxt) && (annolen) && (annotxt + annolen > annotxt) // overflow checks. + && (annotxt+annolen <= dwMemLength)) + { +@@ -710,8 +711,8 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + m_lpszSongComments[annolen] = 0; + } + // Song Name +- uint32_t songname = bswapBE32(pmex->songname); +- uint32_t songnamelen = bswapBE32(pmex->songnamelen); ++ uint32_t songname = READ_BE32(pmex + offsetof(MMD0EXP,songname)); ++ uint32_t songnamelen = READ_BE32(pmex + offsetof(MMD0EXP,songnamelen)); + if ((songname) && (songnamelen) && (songname+songnamelen > songname) + && (songname+songnamelen <= dwMemLength)) + { +@@ -720,12 +721,12 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + m_szNames[0][31] = '\0'; + } + // Sample Names +- DWORD smpinfoex = bswapBE32(pmex->iinfo); ++ DWORD smpinfoex = READ_BE32(pmex + offsetof(MMD0EXP,iinfo)); + if (smpinfoex) + { +- DWORD iinfoptr = bswapBE32(pmex->iinfo); +- UINT ientries = bswapBE16(pmex->i_ext_entries); +- UINT ientrysz = bswapBE16(pmex->i_ext_entrsz); ++ DWORD iinfoptr = READ_BE32(pmex + offsetof(MMD0EXP,iinfo)); ++ UINT ientries = READ_BE16(pmex + offsetof(MMD0EXP,i_ext_entries)); ++ UINT ientrysz = READ_BE16(pmex + offsetof(MMD0EXP,i_ext_entrsz)); + + if ((iinfoptr) && (ientrysz < 256) && + (ientries*ientrysz < dwMemLength) && +@@ -743,14 +744,14 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + } + } + // Track Names +- DWORD trackinfo_ofs = bswapBE32(pmex->trackinfo_ofs); ++ DWORD trackinfo_ofs = READ_BE32(pmex + offsetof(MMD0EXP,trackinfo_ofs)); + if ((trackinfo_ofs) && (trackinfo_ofs < dwMemLength) && (m_nChannels * 4 < dwMemLength - trackinfo_ofs)) + { +- DWORD *ptrktags = (DWORD *)(lpStream + trackinfo_ofs); +- for (UINT i=0; i dwMemLength - 4*m_nSamples) return TRUE; +- pdwTable = (LPDWORD)(lpStream + dwSmplArr); +- for (UINT iSmp=0; iSmp= dwMemLength) || (dwPos + sizeof(MMDSAMPLEHEADER) >= dwMemLength)) continue; +- MMDSAMPLEHEADER *psdh = (MMDSAMPLEHEADER *)(lpStream + dwPos); +- UINT len = bswapBE32(psdh->length); ++ const BYTE *psdh = lpStream + dwPos; /* MMDSAMPLEHEADER */ ++ UINT len = READ_BE32(psdh + offsetof(MMDSAMPLEHEADER,length)); + #ifdef MED_LOG +- Log("SampleData %d: stype=0x%02X len=%d\n", iSmp, bswapBE16(psdh->type), len); ++ Log("SampleData %d: stype=0x%02X len=%d\n", iSmp, READ_BE16(psdh + offsetof(MMDSAMPLEHEADER,type)), len); + #endif + if ((len > MAX_SAMPLE_LENGTH) || (dwPos + len + 6 > dwMemLength)) len = 0; +- UINT flags = RS_PCM8S, stype = bswapBE16(psdh->type); ++ UINT sflags = RS_PCM8S, stype = READ_BE16(psdh + offsetof(MMDSAMPLEHEADER,type)); + LPSTR psdata = (LPSTR)(lpStream + dwPos + 6); + UINT bLimit = dwMemLength - dwPos - 6; + if (stype & 0x80) +@@ -801,25 +803,25 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + { + Ins[iSmp+1].uFlags |= CHN_16BIT; + len /= 2; +- flags = (stype & 0x20) ? RS_STPCM16M : RS_PCM16M; ++ sflags = (stype & 0x20) ? RS_STPCM16M : RS_PCM16M; + } else + { +- flags = (stype & 0x20) ? RS_STPCM8S : RS_PCM8S; ++ sflags = (stype & 0x20) ? RS_STPCM8S : RS_PCM8S; + } + if (stype & 0x20) len /= 2; + } + Ins[iSmp+1].nLength = len; +- ReadSample(&Ins[iSmp+1], flags, psdata, bLimit); ++ ReadSample(&Ins[iSmp+1], sflags, psdata, bLimit); + } + // Reading patterns (blocks) + if (wNumBlocks > MAX_PATTERNS) wNumBlocks = MAX_PATTERNS; + if ((!dwBlockArr) || (dwMemLength < 4*wNumBlocks) || + (dwBlockArr > dwMemLength - 4*wNumBlocks)) return TRUE; +- pdwTable = (LPDWORD)(lpStream + dwBlockArr); ++ pdwTable = lpStream + dwBlockArr; + playtransp += (version == '3') ? 24 : 48; + for (UINT iBlk=0; iBlk= dwMemLength) || (dwPos >= dwMemLength - 8)) continue; + UINT lines = 64, tracks = 4; + if (version == '0') +@@ -847,37 +849,37 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + p->command = s[1] & 0x0F; + p->param = s[2]; + // if (!iBlk) Log("%02X.%02X.%02X | ", s[0], s[1], s[2]); +- MedConvert(p, pmsh); ++ MedConvert(p, flags, flags2); + p++; + } + //if (!iBlk) Log("\n"); + } + } else + { +- const MMD1BLOCK *pmb = (MMD1BLOCK *)(lpStream + dwPos); ++ const BYTE *pmb = lpStream + dwPos; /* MMD1BLOCK */ ++ tracks = READ_BE16(pmb + 0); ++ lines = READ_BE16(pmb + 2) + 1; ++ DWORD dwBlockInfo = READ_BE32(pmb + 4); + #ifdef MED_LOG + Log("MMD1BLOCK: lines=%2d, tracks=%2d, offset=0x%04X\n", +- bswapBE16(pmb->lines), bswapBE16(pmb->numtracks), bswapBE32(pmb->info)); ++ lines, tracks, dwBlockInfo); + #endif +- const MMD1BLOCKINFO *pbi = NULL; + BYTE *pcmdext = NULL; +- lines = (pmb->lines >> 8) + 1; +- tracks = pmb->numtracks >> 8; + if (!tracks) tracks = m_nChannels; + if ((Patterns[iBlk] = AllocatePattern(lines, m_nChannels)) == NULL) continue; + PatternSize[iBlk] = (WORD)lines; +- DWORD dwBlockInfo = bswapBE32(pmb->info); + if ((dwBlockInfo) && (dwBlockInfo < dwMemLength - sizeof(MMD1BLOCKINFO))) + { +- pbi = (MMD1BLOCKINFO *)(lpStream + dwBlockInfo); ++ const BYTE *pbi = lpStream + dwBlockInfo; /* MMD1BLOCKINFO */ ++ DWORD nameofs = READ_BE32(pbi + 4); ++ DWORD namelen = READ_BE32(pbi + 8); ++ DWORD cmdexttable = READ_BE32(pbi + 16); + #ifdef MED_LOG + Log(" BLOCKINFO: blockname=0x%04X namelen=%d pagetable=0x%04X &cmdexttable=0x%04X\n", +- bswapBE32(pbi->blockname), bswapBE32(pbi->blocknamelen), bswapBE32(pbi->pagetable), bswapBE32(pbi->cmdexttable)); ++ nameofs, namelen, READ_BE32(pbi + 12), cmdexttable); + #endif +- if ((pbi->blockname) && (pbi->blocknamelen)) ++ if (nameofs && namelen) + { +- DWORD nameofs = bswapBE32(pbi->blockname); +- UINT namelen = bswapBE32(pbi->blocknamelen); + if ((namelen < dwMemLength) && (nameofs < dwMemLength - namelen)) + { + // SetPatternName expects a nul-terminated string. +@@ -889,9 +891,8 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + SetPatternName(iBlk, blockname); + } + } +- if (pbi->cmdexttable) ++ if (cmdexttable) + { +- DWORD cmdexttable = bswapBE32(pbi->cmdexttable); + if (cmdexttable < dwMemLength - 4) + { + cmdexttable = READ_BE32(lpStream + cmdexttable); +@@ -922,7 +923,7 @@ BOOL CSoundFile::ReadMed(const BYTE *lpStream, DWORD dwMemLength) + p->command = s[2]; + p->param = s[3]; + if (pcmdext) p->vol = pcmdext[x]; +- MedConvert(p, pmsh); ++ MedConvert(p, flags, flags2); + p++; + } + if (pcmdext) pcmdext += tracks; +-- +2.37.2 +