https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2a5536c540ce5d075bf4ea12cc185140f8431953

commit 2a5536c540ce5d075bf4ea12cc185140f8431953
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sat Jan 29 18:42:23 2022 +0100
Commit:     Hermès Bélusca-Maïto <[email protected]>
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;
 

Reply via email to