Ticket #13777: 0001-IMuseDigital-fix-unaligned-access.patch

File 0001-IMuseDigital-fix-unaligned-access.patch, 2.2 KB (added by kreudom, 21 months ago)
  • engines/scumm/imuse_digi/dimuse_dispatch.cpp

    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) {  
    11491149                        while (mapCurPos < endOfMapPtr) {
    11501150                                // Swap32 the 4 characters block name
    11511151                                int32 swapped = READ_BE_UINT32(mapCurPos);
    1152                                 *(int32 *)mapCurPos = swapped;
     1152                                memcpy(mapCurPos, &swapped, 4);
    11531153                                blockName = swapped;
    11541154
    11551155                                // Advance and Swap32 the block size (minus 8) field
    11561156                                blockSizePtr = mapCurPos + 4;
    11571157                                blockSizeMin8 = READ_BE_UINT32(blockSizePtr);
    1158                                 *(int32 *)blockSizePtr = blockSizeMin8;
     1158                                memcpy(blockSizePtr, &blockSizeMin8, 4);
    11591159                                mapCurPos = blockSizePtr + 4;
    11601160
    11611161                                // Swapping32 a TEXT block is different:
    int IMuseDigital::dispatchConvertMap(uint8 *rawMap, uint8 *destMap) {  
    11631163                                // since they're already good like this
    11641164                                if (blockName == MKTAG('T', 'E', 'X', 'T')) {
    11651165                                        // Swap32 the block offset position
    1166                                         *(int32 *)mapCurPos = READ_BE_UINT32(mapCurPos);
     1166                                        swapped = READ_BE_UINT32(mapCurPos);
     1167                                        memcpy(mapCurPos, &swapped, 4);
    11671168
    11681169                                        // Skip the single characters
    11691170                                        firstChar = mapCurPos + 4;
    int IMuseDigital::dispatchConvertMap(uint8 *rawMap, uint8 *destMap) {  
    11801181
    11811182                                        // ...and swap them of course
    11821183                                        do {
    1183                                                 *(int32 *)mapCurPos = READ_BE_UINT32(mapCurPos);
     1184                                                swapped = READ_BE_UINT32(mapCurPos);
     1185                                                memcpy(mapCurPos, &swapped, 4);
    11841186                                                mapCurPos += 4;
    11851187                                                --remainingFieldsNum;
    11861188                                        } while (remainingFieldsNum);