https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2a5536c540ce5d075bf4e…
commit 2a5536c540ce5d075bf4ea12cc185140f8431953
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jan 29 18:42:23 2022 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)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;