Ticket #8959: bs1_portuguese_crash.patch

File bs1_portuguese_crash.patch, 5.8 KB (added by criezy, 12 years ago)

Patch to avoid crash with BS1 that do not have portuguese subtitles

  • engines/sword1/objectman.cpp

    diff -ruN scummvm-20090214-orig/engines/sword1/objectman.cpp scummvm-20090214/engines/sword1/objectman.cpp
    old new  
    101101
    102102char *ObjectMan::lockText(uint32 textId) {
    103103        uint8 lang = SwordEngine::_systemVars.language;
    104         char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]) + sizeof(Header);
     104        char *addr = (char*)_resMan->openFetchRes(_textList[textId / ITM_PER_SEC][lang]);
     105        if (addr == 0)
     106                return _errorStr;
     107        addr += sizeof(Header);
    105108        if ((textId & ITM_ID) >= _resMan->readUint32(addr)) {
    106109                warning("ObjectMan::lockText(%d): only %d texts in file", textId & ITM_ID, _resMan->readUint32(addr));
    107110                textId = 0; // get first line instead
  • engines/sword1/resman.cpp

    diff -ruN scummvm-20090214-orig/engines/sword1/resman.cpp scummvm-20090214/engines/sword1/resman.cpp
    old new  
    199199
    200200void *ResMan::fetchRes(uint32 id) {
    201201        MemHandle *memHandle = resHandle(id);
     202        if (!memHandle) {
     203                warning("fetchRes:: resource %d out of bounds!", id);
     204                return NULL;
     205        }
    202206        if (!memHandle->data)
    203207                error("fetchRes:: resource %d is not open!", id);
    204208        return memHandle->data;
     
    216220        if (outf.open(outn)) {
    217221                resOpen(id);
    218222                MemHandle *memHandle = resHandle(id);
    219                 outf.write(memHandle->data, memHandle->size);
    220                 outf.close();
     223                if (memHandle) {
     224                        outf.write(memHandle->data, memHandle->size);
     225                        outf.close();
     226                }
    221227                resClose(id);
    222228        }
    223229}
     
    244250#else
    245251        openCptResourceLittleEndian(id);
    246252#endif
    247         return resHandle(id)->data;
     253        MemHandle *handle = resHandle(id);
     254        return handle != NULL ? handle->data : NULL;
    248255}
    249256
    250257void ResMan::resOpen(uint32 id) {  // load resource ID into memory
    251258        MemHandle *memHandle = resHandle(id);
     259        if (!memHandle)
     260                return;
    252261        if (memHandle->cond == MEM_FREED) { // memory has been freed
    253262                uint32 size = resLength(id);
    254263                _memMan->alloc(memHandle, size);
     
    270279
    271280void ResMan::resClose(uint32 id) {
    272281        MemHandle *handle = resHandle(id);
     282        if (!handle)
     283                return;
    273284        if (!handle->refCount) {
    274285                warning("Resource Manager fail: unlocking object with refCount 0. Id: %d\n", id);
    275286        } else {
     
    313324                else
    314325                        sprintf(fileName, "%s.CLU", _prj.clu[(id >> 24)-1].label);
    315326                cluster->file->open(fileName);
    316 
    317327                if (!cluster->file->isOpen()) {
    318328                        char msg[512];
    319329                        sprintf(msg, "Couldn't open game cluster file '%s'\n\nIf you are running from CD, please ensure you have read the ScummVM documentation regarding multi-cd games.", fileName);
     
    340350        uint8 cluster = (uint8)((id >> 24) - 1);
    341351        uint8 group = (uint8)(id >> 16);
    342352
     353        // There is a know case of reading beyond array boundaries when trying to use
     354        // portuguese subtitles (cluster file 2, group 6) with a version that do not
     355        // contain subtitles for this languages (i.e. has only 6 languages and not 7).
     356        if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
     357                return NULL;   
     358       
    343359        return &(_prj.clu[cluster].grp[group].resHandle[id & 0xFFFF]);
    344360}
    345361
     
    349365        uint8 cluster = (uint8)((id >> 24) - 1);
    350366        uint8 group = (uint8)(id >> 16);
    351367
     368        if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
     369                return 0;
     370
    352371        return _prj.clu[cluster].grp[group].length[id & 0xFFFF];
    353372}
    354373
     
    357376                id = _srIdList[id & 0xFFFF];
    358377        uint8 cluster = (uint8)((id >> 24) - 1);
    359378        uint8 group = (uint8)(id >> 16);
     379       
     380        if (cluster >= _prj.noClu || group >= _prj.clu[cluster].noGrp)
     381                return 0;
    360382
    361383        return _prj.clu[cluster].grp[group].offset[id & 0xFFFF];
    362384}
     
    368390                // If the resource are not in memory anymore, and therefore will be read
    369391                // from disk, they will need to be byte swaped.
    370392                MemHandle *memHandle = resHandle(id);
    371                 needByteSwap = (memHandle->cond == MEM_FREED);
     393                if (memHandle)
     394                        needByteSwap = (memHandle->cond == MEM_FREED);
    372395        }
    373396        resOpen(id);
    374397        if (needByteSwap) {
    375398                MemHandle *handle = resHandle(id);
     399                if (!handle)
     400                        return;
    376401                uint32 totSize = handle->size;
    377402                uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
    378403                totSize -= sizeof(Header);
     
    393418                // If the resource are not in memory anymore, and therefore will be read
    394419                // from disk, they will need to be byte swaped.
    395420                MemHandle *memHandle = resHandle(id);
    396                 needByteSwap = (memHandle->cond == MEM_FREED);
     421                if (memHandle)
     422                        needByteSwap = (memHandle->cond == MEM_FREED);
    397423        }
    398424        resOpen(id);
    399425        if (needByteSwap) {
    400426                MemHandle *handle = resHandle(id);
     427                if (!handle)
     428                        return;
    401429                uint32 totSize = handle->size;
    402430                uint32 *data = (uint32*)((uint8*)handle->data + sizeof(Header));
    403431                totSize -= sizeof(Header);
     
    418446                // If the resource are not in memory anymore, and therefore will be read
    419447                // from disk, they will need to be byte swaped.
    420448                MemHandle *memHandle = resHandle(id);
    421                 needByteSwap = (memHandle->cond == MEM_FREED);
     449                if (memHandle)
     450                        needByteSwap = (memHandle->cond == MEM_FREED);
    422451        }
    423452        resOpen(id);
    424453        if (needByteSwap) {
    425454                MemHandle *handle = resHandle(id);
     455                if (!handle)
     456                        return;
    426457                // uint32 totSize = handle->size;
    427458                Header *head = (Header*)handle->data;
    428459                head->comp_length = FROM_LE_32(head->comp_length);
     
    447478                // If the resource are not in memory anymore, and therefore will be read
    448479                // from disk, they will need to be byte swaped.
    449480                MemHandle *memHandle = resHandle(id);
    450                 needByteSwap = (memHandle->cond == MEM_FREED);
     481                if (memHandle)
     482                        needByteSwap = (memHandle->cond == MEM_FREED);
    451483        }
    452484        resOpen(id);
    453485        if (needByteSwap) {
    454486                MemHandle *handle = resHandle(id);
     487                if (!handle)
     488                        return;
    455489                // uint32 totSize = handle->size;
    456490                Header *head = (Header*)handle->data;
    457491                head->comp_length = FROM_BE_32(head->comp_length);