nrosenstein-c4d / c4d-resedit

Fork of the official MAXON Cinema 4D ResEdit plugin
Apache License 2.0
2 stars 1 forks source link

CLanguageList::Init() assumes pre-R16 resource directory structure #4

Closed NiklasRosenstein closed 8 years ago

NiklasRosenstein commented 8 years ago

This causes CLanguageList g_LanguageList; in globals.cpp to be initialized with zero languages, effectively causing a crash in CStringTableElement::SetItemText() (if not earlier) when a description is being saved with ResEdit.

This is the respective code in LanguageList.cpp

/*********************************************************************\
    Function name    : CLanguageList::Init
    Description      :
    Created at       : 26.09.01, @ 16:11:23
    Created by       : Thomas Kunert
    Modified by      :
\*********************************************************************/
void CLanguageList::Init()
{
    Filename resourcepath = GeGetStartupPath() + Filename("resource");
    AutoAlloc <BrowseFiles> pBrowse;
    pBrowse->Init(resourcepath, false);

    while (pBrowse->GetNext())
    {
        if (pBrowse->IsDir())
        {
            Filename fn = pBrowse->GetFilename();
            if (fn.GetString().SubStr(0, 8).ToLower() == "strings_")
            {
                String idx = fn.GetString();
                idx.Delete(0, 8);

                Filename stringname = resourcepath + fn+Filename("c4d_language.str");
                AutoAlloc <BaseFile> pFile;
                if (!pFile)
                    return;
                if (!GeFExist(stringname))
                {
                    GeOutString("Missing c4d_language.str to identify the string directory!!!", GEMB_ICONEXCLAMATION);
                }
                else if (pFile->Open(stringname))
                {
                    Int32 len = pFile->GetLength();
                    Char *buffer = NewMemClear(Char,len + 2);
                    if (buffer)
                    {
                        pFile->ReadBytes(buffer,len);
                        buffer[len]=0;

                        Int32 i;

                        for (i = 0; i < len && buffer[i] >= ' '; i++) { }
                        buffer[i] = 0;

                        for (i--; i > 0 && buffer[i]== ' '; i--) { }
                        buffer[i + 1] = 0;

                        AddLanguage(buffer, idx);
                        DeleteMem(buffer);
                    }
                }
            }
        }
    }
}
NiklasRosenstein commented 8 years ago

dc2f7cd uses preprocessor definitions to check the API version, but we must base the decision on the runtime version of Cinema 4D.