From 7f2c60e372afe8c39346fc9ba0ad9fe50be5f045 Mon Sep 17 00:00:00 2001
From: Dominik Kreutzer <kreudom@gmail.com>
Date: Fri, 12 Aug 2022 20:22:25 +0200
Subject: [PATCH] IMuseDigital: fix unaligned access
If dispatchConvertMap is called with a map that contains a TEXT block and
if the length of that block is not divisible by 4, using mapCurPos as an
int32 pointer results in undefined behaviour, because it is unaligned.
---
engines/scumm/imuse_digi/dimuse_dispatch.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/engines/scumm/imuse_digi/dimuse_dispatch.cpp b/engines/scumm/imuse_digi/dimuse_dispatch.cpp
index ff0d7be7280..1ad0a52e253 100644
a
|
b
|
int IMuseDigital::dispatchConvertMap(uint8 *rawMap, uint8 *destMap) {
|
1149 | 1149 | while (mapCurPos < endOfMapPtr) { |
1150 | 1150 | // Swap32 the 4 characters block name |
1151 | 1151 | int32 swapped = READ_BE_UINT32(mapCurPos); |
1152 | | *(int32 *)mapCurPos = swapped; |
| 1152 | memcpy(mapCurPos, &swapped, 4); |
1153 | 1153 | blockName = swapped; |
1154 | 1154 | |
1155 | 1155 | // Advance and Swap32 the block size (minus 8) field |
1156 | 1156 | blockSizePtr = mapCurPos + 4; |
1157 | 1157 | blockSizeMin8 = READ_BE_UINT32(blockSizePtr); |
1158 | | *(int32 *)blockSizePtr = blockSizeMin8; |
| 1158 | memcpy(blockSizePtr, &blockSizeMin8, 4); |
1159 | 1159 | mapCurPos = blockSizePtr + 4; |
1160 | 1160 | |
1161 | 1161 | // Swapping32 a TEXT block is different: |
… |
… |
int IMuseDigital::dispatchConvertMap(uint8 *rawMap, uint8 *destMap) {
|
1163 | 1163 | // since they're already good like this |
1164 | 1164 | if (blockName == MKTAG('T', 'E', 'X', 'T')) { |
1165 | 1165 | // Swap32 the block offset position |
1166 | | *(int32 *)mapCurPos = READ_BE_UINT32(mapCurPos); |
| 1166 | swapped = READ_BE_UINT32(mapCurPos); |
| 1167 | memcpy(mapCurPos, &swapped, 4); |
1167 | 1168 | |
1168 | 1169 | // Skip the single characters |
1169 | 1170 | firstChar = mapCurPos + 4; |
… |
… |
int IMuseDigital::dispatchConvertMap(uint8 *rawMap, uint8 *destMap) {
|
1180 | 1181 | |
1181 | 1182 | // ...and swap them of course |
1182 | 1183 | do { |
1183 | | *(int32 *)mapCurPos = READ_BE_UINT32(mapCurPos); |
| 1184 | swapped = READ_BE_UINT32(mapCurPos); |
| 1185 | memcpy(mapCurPos, &swapped, 4); |
1184 | 1186 | mapCurPos += 4; |
1185 | 1187 | --remainingFieldsNum; |
1186 | 1188 | } while (remainingFieldsNum); |