https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2a5536c540ce5d075bf4ea...
commit 2a5536c540ce5d075bf4ea12cc185140f8431953 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Sat Jan 29 18:42:23 2022 +0100 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org CommitDate: Sun Jan 30 01:02:08 2022 +0100
[CONSOLE.CPL] Rewrite the BuildCodePageList() registry enumeration loop and use far less stack space.
Any valid code page value name in System\CurrentControlSet\Control\Nls\CodePage is a string representation of its corresponding decimal value, that cannot be larger than MAXUSHORT == 65535, i.e. longer than 5+1 characters.
Noticed with the analyser warning dll\cpl\console\options.c(74): warning C6262: Function uses '32808' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap.
Make the enumeration loop actually stop when ERROR_NO_MORE_ITEMS is returned. If we got another error, e.g. because the value name was too long (and thus, an invalid code page), just ignore and continue looping. --- dll/cpl/console/options.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-)
diff --git a/dll/cpl/console/options.c b/dll/cpl/console/options.c index 57e34d96f06..687b52c0f1d 100644 --- a/dll/cpl/console/options.c +++ b/dll/cpl/console/options.c @@ -76,17 +76,23 @@ BuildCodePageList( IN UINT CurrentCodePage) { LIST_CTL ListCtl; + LRESULT lResult; HKEY hKey; - DWORD dwIndex, dwSize, dwType; + DWORD dwIndex, dwType; + DWORD cchValueName; UINT CodePage; - WCHAR szValueName[MAX_VALUE_NAME];
- // #define REGSTR_PATH_CODEPAGE TEXT("System\CurrentControlSet\Control\Nls\CodePage") + /* Valid code page value names are string representations + * of their corresponding decimal values, that are not larger + * than MAXUSHORT == 65535. */ + WCHAR szValueName[sizeof("65535")]; + /* Open the Nls\CodePage key */ + // #define REGSTR_PATH_CODEPAGE TEXT("System\CurrentControlSet\Control\Nls\CodePage") if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\CurrentControlSet\Control\Nls\CodePage", 0, - KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, + KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) { return; @@ -97,16 +103,26 @@ BuildCodePageList( ListCtl.GetData = List_GetData;
/* Enumerate all the available code pages on the system */ - dwSize = ARRAYSIZE(szValueName); - dwIndex = 0; - while (RegEnumValueW(hKey, dwIndex, szValueName, &dwSize, - NULL, &dwType, NULL, NULL) == ERROR_SUCCESS) // != ERROR_NO_MORE_ITEMS + for (dwIndex = 0, cchValueName = ARRAYSIZE(szValueName); + (lResult = RegEnumValueW(hKey, dwIndex, + szValueName, &cchValueName, + NULL, &dwType, + NULL, NULL)) != ERROR_NO_MORE_ITEMS; + ++dwIndex, cchValueName = ARRAYSIZE(szValueName)) { - /* Ignore these parameters, prepare for next iteration */ - dwSize = ARRAYSIZE(szValueName); - ++dwIndex; + /* Ignore if we failed for another reason, e.g. because + * the value name is too long (and thus, invalid). */ + if (lResult != ERROR_SUCCESS) + continue; + + /* Validate the value name (exclude the unnamed value) */ + if (!cchValueName || (*szValueName == UNICODE_NULL)) + continue; + /* Too large value names have already been handled with ERROR_MORE_DATA */ + ASSERT((cchValueName < ARRAYSIZE(szValueName)) && + (szValueName[cchValueName] == UNICODE_NULL));
- /* Check the value type validity */ + /* Validate the value type */ if (dwType != REG_SZ) continue;