From efcf164abe29eaf3357a63219830af4a71058af4 Mon Sep 17 00:00:00 2001 From: Nastasie Ion Octavian Date: Sun, 4 Aug 2019 11:18:46 +0300 Subject: [PATCH] Fix enum_settings_next() to handle subkeys with 256 characters long names. Set the initial buffer size to MAX_PATH + 1 (261). Increment e->i before the function returns instead of incrementing it in the call to RegEnumKey. The initial buffer size was too small to fit a subkey with a 256 characters long name plus '\0', the first call to RegEnumKey would fail with ERROR_MORE_DATA, sgrowarray would grow the buffer, and RegEnumKey would be called again. However, because e->i was incremented in the first RegEnumKey call, the second call would get the next subkey and the subkey with the long name would be skipped. Saving a session with a 256 characters long name would trigger this problem. The session would be saved in the registry, but Putty would not be able to display it in the saved sessions list. Pageant didn't have this problem since it uses a different function to get the saved sessions and the size of the buffer used is MAX_PATH + 1. Pageant and Putty would display slightly different lists of saved sessions. --- windows/winstore.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/windows/winstore.c b/windows/winstore.c index 01ee86f9..260fa20f 100644 --- a/windows/winstore.c +++ b/windows/winstore.c @@ -288,12 +288,12 @@ settings_e *enum_settings_start(void) bool enum_settings_next(settings_e *e, strbuf *sb) { - size_t regbuf_size = 256; + size_t regbuf_size = MAX_PATH + 1; char *regbuf = snewn(regbuf_size, char); bool success; while (1) { - DWORD retd = RegEnumKey(e->key, e->i++, regbuf, regbuf_size); + DWORD retd = RegEnumKey(e->key, e->i, regbuf, regbuf_size); if (retd != ERROR_MORE_DATA) { success = (retd == ERROR_SUCCESS); break; @@ -304,6 +304,7 @@ bool enum_settings_next(settings_e *e, strbuf *sb) if (success) unescape_registry_key(regbuf, sb); + e->i++; sfree(regbuf); return success; }