Page 1 of 1

The "RenameFile.js" script causes program crash

Posted: Mon Jun 09, 2025 4:16 am
by drkh
Hi,

I use AkelPad 4.9.9 x64 in Windows 11 Pro 24H2. There is a problem with the "RenameFile.js" script.

In an AkelPad session, after that script is called, you can see 2 buttons in its GUI dialog: OK and Cancel. Also there is a text field where the filename is shown and can be changed.

If I do change the filename and click the OK button, all is fine. No problem. But, if I don't change the filename and click either the OK button or the Cancel button, the whole AkelPad window will disappear in about 2 seconds(crashing?). Also, if I change the filename but click the Cancel button, the AkelPad window will disappear, too.

But, when that script is run in another PC under Windows 10 Pro 1709 x86, there is no problem. So I tried the 32-bit version of AkelPad 4.9.9 (after uninstalling the 64-bit version) under the same Windows 11 Pro 24H2 PC. The same problem occurred.

How can I fix that problem?

PS:

(1) Please also take a look at my next message below.

(2) I'm attaching the contents of the "RenameFile.js" script here:

Code: Select all

// http://akelpad.sourceforge.net/en/plugins.php#Scripts
// Version: 1.1
// Author: Shengalts Aleksander aka Instructor
//
// Description(1033): Rename current editing file.
// Description(1049): Х񦩬殮㡲 󦫳駠��.

//Variables
var hMainWnd=AkelPad.GetMainWnd();
var hWndEdit=AkelPad.GetEditWnd();
var oSys=AkelPad.SystemFunction();
var pFileFullName=AkelPad.GetEditFile(0);
var pFileName=AkelPad.GetFilePath(pFileFullName, 2 /*CPF_FILENAME*/);
var pFileDir=AkelPad.GetFilePath(pFileFullName, 1 /*CPF_DIR*/);
var pNewFileFullName="";
var lpPoint64;
var lpSel;
var lpCaret;
var nCodePage;
var nBOM;
var dwFlags;

if (hWndEdit)
{
  if (!pFileFullName)
  {
    AkelPad.MessageBox(hMainWnd, GetLangString(1), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
    WScript.Quit();
  }

  for (;;)
  {
    pFileName=AkelPad.InputBox(hMainWnd, WScript.ScriptName, GetLangString(0), pFileName);
    if (!pFileName)
      WScript.Quit();

    pNewFileFullName=pFileDir + "\\" + pFileName;
    if (pNewFileFullName == pFileFullName)
      WScript.Quit();

    if (IsFileExist(pNewFileFullName))
      AkelPad.MessageBox(hMainWnd, GetLangString(2).replace(/%s/, pNewFileFullName), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
    else
      break;
  }

  if (lpPoint64=AkelPad.MemAlloc(_X64?16:8 /*sizeof(POINT64)*/))
  {
    if (lpSel=AkelPad.MemAlloc(_X64?56:32 /*sizeof(AESELECTION)*/))
    {
      if (lpCaret=AkelPad.MemAlloc(_X64?24:12 /*sizeof(AECHARINDEX)*/))
      {
        //Get document state
        AkelPad.SendMessage(hWndEdit, 3179 /*AEM_GETSCROLLPOS*/, 0, lpPoint64);
        AkelPad.SendMessage(hWndEdit, 3125 /*AEM_GETSEL*/, lpCaret, lpSel);
        nCodePage=AkelPad.GetEditCodePage(hWndEdit);
        nBOM=AkelPad.GetEditBOM(hWndEdit);

        //Close editing file
        if (AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4324 /*IDM_WINDOW_FILECLOSE*/, 0))
        {
          //Rename file
          if (!oSys.Call("kernel32::MoveFile" + _TCHAR, pFileFullName, pNewFileFullName))
          {
            AkelPad.MessageBox(hMainWnd, GetLangString(3).replace(/%d/, "" + oSys.GetLastError()), WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);
            pNewFileFullName=pFileFullName;
          }

          //Open file
          AkelPad.OpenFile(pNewFileFullName, 0, nCodePage, nBOM);

          //Restore document position
          dwFlags=AkelPad.MemRead(_PtrAdd(lpSel, _X64?48:24) /*offsetof(AESELECTION, dwFlags)*/, 3 /*DT_DWORD*/);
          AkelPad.MemCopy(_PtrAdd(lpSel, _X64?48:24) /*offsetof(AESELECTION, dwFlags)*/, dwFlags | 0x808 /*AESELT_LOCKSCROLL|AESELT_INDEXUPDATE*/, 3 /*DT_DWORD*/);
          AkelPad.SendMessage(hWndEdit, 3126 /*AEM_SETSEL*/, lpCaret, lpSel);
          AkelPad.SendMessage(hWndEdit, 3180 /*AEM_SETSCROLLPOS*/, 0, lpPoint64);
        }
        AkelPad.MemFree(lpCaret);
      }
      AkelPad.MemFree(lpSel);
    }
    AkelPad.MemFree(lpPoint64);
  }
}


//Functions
function IsFileExist(pFile)
{
  if (oSys.Call("kernel32::GetFileAttributes" + _TCHAR, pFile) == -1)
    return false;
  return true;
}

function GetLangString(nStringID)
{
  var nLangID=AkelPad.GetLangId(1 /*LANGID_PRIMARY*/);

  if (nLangID == 0x19) //LANG_RUSSIAN
  {
    if (nStringID == 0)
      return "\u041D\u043E\u0432\u043E\u0435\u0020\u0438\u043C\u044F\u003A";
    if (nStringID == 1)
      return "\u0421\u043F\u0435\u0440\u0432\u0430\u0020\u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u0435\u0020\u0444\u0430\u0439\u043B\u002E";
    if (nStringID == 2)
      return "\u0424\u0430\u0439\u043B \"%s\" \u0443\u0436\u0435\u0020\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\u002E";
    if (nStringID == 3)
      return "\u041E\u0448\u0438\u0431\u043A\u0430 MoveFile: \"%d\".";
  }
  else
  {
    if (nStringID == 0)
      return "New name:";
    if (nStringID == 1)
      return "Save file first.";
    if (nStringID == 2)
      return "File \"%s\" already exists.";
    if (nStringID == 3)
      return "MoveFile error: \"%d\".";
  }
  return "";
}

Re: The "RenameFile.js" script causes program crash

Posted: Mon Jun 09, 2025 4:16 am
by drkh
Actually I have asked ChatGPT about this problem. See here, if you care:

https://chatgpt.com/share/68465afd-0310 ... faf4ae1a22

ChatGPT thinks the root cause of the problem lies in the following 2 blocks of the script. Also, ChatGPT gives a fixed version of the script. But the new version does not fix the problem. I also tried the Compatibility mode (Win8. no Win10) for both x86 and x64 version of AkelPad, but in vain.

(1)

if (pNewFileFullName == pFileFullName)
WScript.Quit();


ChatGPT notes:

"When this condition is true (i.e., user didn't change the name), it simply exits the script after allocating memory and before freeing it. That's dangerous, especially if AkelPad depends on the cleanup (like freeing the memory it allocates in the script context)."


(2)

if (!pFileName)
WScript.Quit();


ChatGPT note:

"This happens when the user clicks Cancel — again, it quits without freeing any previously allocated memory.

On some systems (like Windows 10), this might not cause a crash. But on Windows 11 with tighter memory handling, these unfreed or dangling memory allocations may corrupt AkelPad's state and result in a delayed crash (~2 seconds after dialog closes, as you observed)."

You should free all allocated memory before quitting, no matter what path the script takes. Here is a fixed version of your script, with memory-safe exits:

Code: Select all

// Fixed version with safe memory cleanup
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var pFileFullName = AkelPad.GetEditFile(0);
var pFileName = AkelPad.GetFilePath(pFileFullName, 2);
var pFileDir = AkelPad.GetFilePath(pFileFullName, 1);
var pNewFileFullName = "";
var lpPoint64 = 0;
var lpSel = 0;
var lpCaret = 0;
var nCodePage = 0;
var nBOM = 0;
var dwFlags = 0;

function cleanupAndExit() {
  if (lpCaret) AkelPad.MemFree(lpCaret);
  if (lpSel) AkelPad.MemFree(lpSel);
  if (lpPoint64) AkelPad.MemFree(lpPoint64);
  WScript.Quit();
}

if (hWndEdit) {
  if (!pFileFullName) {
    AkelPad.MessageBox(hMainWnd, GetLangString(1), WScript.ScriptName, 48);
    WScript.Quit();
  }

  for (;;) {
    pFileName = AkelPad.InputBox(hMainWnd, WScript.ScriptName, GetLangString(0), pFileName);
    if (!pFileName) cleanupAndExit();

    pNewFileFullName = pFileDir + "\\" + pFileName;

    if (pNewFileFullName == pFileFullName) cleanupAndExit();

    if (IsFileExist(pNewFileFullName))
      AkelPad.MessageBox(hMainWnd, GetLangString(2).replace(/%s/, pNewFileFullName), WScript.ScriptName, 48);
    else
      break;
  }

  lpPoint64 = AkelPad.MemAlloc(_X64 ? 16 : 8);
  lpSel = AkelPad.MemAlloc(_X64 ? 56 : 32);
  lpCaret = AkelPad.MemAlloc(_X64 ? 24 : 12);

  if (lpPoint64 && lpSel && lpCaret) {
    AkelPad.SendMessage(hWndEdit, 3179, 0, lpPoint64);
    AkelPad.SendMessage(hWndEdit, 3125, lpCaret, lpSel);
    nCodePage = AkelPad.GetEditCodePage(hWndEdit);
    nBOM = AkelPad.GetEditBOM(hWndEdit);

    if (AkelPad.SendMessage(hMainWnd, 273, 4324, 0)) {
      if (!oSys.Call("kernel32::MoveFile" + _TCHAR, pFileFullName, pNewFileFullName)) {
        AkelPad.MessageBox(hMainWnd, GetLangString(3).replace(/%d/, "" + oSys.GetLastError()), WScript.ScriptName, 48);
        pNewFileFullName = pFileFullName;
      }

      AkelPad.OpenFile(pNewFileFullName, 0, nCodePage, nBOM);

      dwFlags = AkelPad.MemRead(_PtrAdd(lpSel, _X64 ? 48 : 24), 3);
      AkelPad.MemCopy(_PtrAdd(lpSel, _X64 ? 48 : 24), dwFlags | 0x808, 3);
      AkelPad.SendMessage(hWndEdit, 3126, lpCaret, lpSel);
      AkelPad.SendMessage(hWndEdit, 3180, 0, lpPoint64);
    }
  }

  cleanupAndExit();
}

function IsFileExist(pFile) {
  return oSys.Call("kernel32::GetFileAttributes" + _TCHAR, pFile) != -1;
}

function GetLangString(nStringID) {
  var nLangID = AkelPad.GetLangId(1);

  if (nLangID == 0x19) {
    if (nStringID == 0) return "\u041D\u043E\u0432\u043E\u0435\u0020\u0438\u043C\u044F\u003A";
    if (nStringID == 1) return "\u0421\u043F\u0435\u0440\u0432\u0430\u0020\u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u0435\u0020\u0444\u0430\u0439\u043B\u002E";
    if (nStringID == 2) return "\u0424\u0430\u0439\u043B \"%s\" \u0443\u0436\u0435\u0020\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442\u002E";
    if (nStringID == 3) return "\u041E\u0448\u0438\u0431\u043A\u0430 MoveFile: \"%d\".";
  } else {
    if (nStringID == 0) return "New name:";
    if (nStringID == 1) return "Save file first.";
    if (nStringID == 2) return "File \"%s\" already exists.";
    if (nStringID == 3) return "MoveFile error: \"%d\".";
  }
  return "";
}

Re: The "RenameFile.js" script causes program crash

Posted: Tue Jun 10, 2025 4:52 am
by Instructor
Make sure you use latest version of Scripts plugin

Re: The "RenameFile.js" script causes program crash

Posted: Tue Jun 10, 2025 9:51 am
by drkh
Instructor wrote: Tue Jun 10, 2025 4:52 am Make sure you use latest version of Scripts plugin
Thank you very much. No problem now.

Something I'm not absolutely sure...

I use the x64 version of AkelPad 4.9.9. So, to replace the "Scripts.dll" file in the "Plugs" folder, I have to pick the file with the same name (123KB) from the "Plugs64" folder in the zip, not the file (99KB) from the "Plugs" folder.

Is that correct?