1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Rewrite some manual char-buffer-handling code.

In the course of recent refactorings I noticed a couple of cases where
we were doing old-fashioned preallocation of a char array with some
conservative maximum size, then writing into it via *p++ or similar
and hoping we got the calculation right.

Now we have strbuf and dupcat, so we shouldn't ever have to do that.
Fixed as many cases as I could find by searching for allocations of
the form 'snewn(foo, char)'.

Particularly worth a mention was the Windows GSSAPI setup code, which
was directly using the Win32 Registry API, and looks much more legible
using the windows/utils/registry.c wrappers. (But that was why I had
to enhance them in the previous commit so as to be able to open
registry keys read-only: without that, the open operation would
actually fail on this key, which is not user-writable.)

Also unix/askpass.c, which was doing a careful reallocation of its
buffer to avoid secrets being left behind in the vacated memory -
which is now just a matter of ensuring we called strbuf_new_nm().
This commit is contained in:
Simon Tatham
2022-09-13 15:00:26 +01:00
parent 7339e00f4a
commit 6cf6682c54
13 changed files with 174 additions and 291 deletions

View File

@ -393,13 +393,11 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, const char *text, int *lines)
INT *pwidths, nfit;
SIZE size;
const char *p;
char *ret, *q;
RECT r;
HFONT oldfont, newfont;
ret = snewn(1+strlen(text), char);
strbuf *sb = strbuf_new();
p = text;
q = ret;
pwidths = snewn(1+strlen(text), INT);
/*
@ -432,7 +430,7 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, const char *text, int *lines)
* Either way, we stop wrapping, copy the remainder of
* the input string unchanged to the output, and leave.
*/
strcpy(q, p);
put_datapl(sb, ptrlen_from_asciz(p));
break;
}
@ -449,9 +447,8 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, const char *text, int *lines)
}
}
strncpy(q, p, nfit);
q[nfit] = '\n';
q += nfit+1;
put_data(sb, p, nfit);
put_byte(sb, '\n');
p += nfit;
while (*p && isspace((unsigned char)*p))
@ -467,7 +464,7 @@ char *staticwrap(struct ctlpos *cp, HWND hwnd, const char *text, int *lines)
sfree(pwidths);
return ret;
return strbuf_to_str(sb);
}
/*
@ -1181,30 +1178,24 @@ void progressbar(struct ctlpos *cp, int id)
*/
static char *shortcut_escape(const char *text, char shortcut)
{
char *ret;
char const *p;
char *q;
if (!text)
return NULL; /* sfree won't choke on this */
ret = snewn(2*strlen(text)+1, char); /* size potentially doubles! */
strbuf *sb = strbuf_new();
shortcut = tolower((unsigned char)shortcut);
p = text;
q = ret;
const char *p = text;
while (*p) {
if (shortcut != NO_SHORTCUT &&
tolower((unsigned char)*p) == shortcut) {
*q++ = '&';
put_byte(sb, '&');
shortcut = NO_SHORTCUT; /* stop it happening twice */
} else if (*p == '&') {
*q++ = '&';
put_byte(sb, '&');
}
*q++ = *p++;
put_byte(sb, *p++);
}
*q = '\0';
return ret;
return strbuf_to_str(sb);
}
void winctrl_add_shortcuts(struct dlgparam *dp, struct winctrl *c)

View File

@ -300,35 +300,21 @@ static INT_PTR CALLBACK LogProc(HWND hwnd, UINT msg,
LB_GETSELITEMS,
selcount,
(LPARAM) selitems);
int i;
int size;
char *clipdata;
static unsigned char sel_nl[] = SEL_NL;
static const unsigned char sel_nl[] = SEL_NL;
if (count == 0) { /* can't copy zero stuff */
MessageBeep(0);
break;
}
size = 0;
for (i = 0; i < count; i++)
size +=
strlen(getevent(selitems[i])) + sizeof(sel_nl);
clipdata = snewn(size, char);
if (clipdata) {
char *p = clipdata;
for (i = 0; i < count; i++) {
char *q = getevent(selitems[i]);
int qlen = strlen(q);
memcpy(p, q, qlen);
p += qlen;
memcpy(p, sel_nl, sizeof(sel_nl));
p += sizeof(sel_nl);
}
write_aclip(hwnd, CLIP_SYSTEM, clipdata, size);
sfree(clipdata);
strbuf *sb = strbuf_new();
for (int i = 0; i < count; i++) {
char *q = getevent(selitems[i]);
put_datapl(sb, ptrlen_from_asciz(q));
put_data(sb, sel_nl, sizeof(sel_nl));
}
write_aclip(hwnd, CLIP_SYSTEM, sb->s, sb->len);
strbuf_free(sb);
sfree(selitems);
for (i = 0; i < (ninitial + ncircular); i++)

View File

@ -118,7 +118,6 @@ static void add_library_to_never_unload_tree(HMODULE module)
struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
{
HMODULE module;
HKEY regkey;
struct ssh_gss_liblist *list = snew(struct ssh_gss_liblist);
char *path;
static HMODULE kernel32_module;
@ -137,55 +136,47 @@ struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
/* MIT Kerberos GSSAPI implementation */
module = NULL;
if (RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\MIT\\Kerberos", &regkey)
== ERROR_SUCCESS) {
DWORD type, size;
LONG ret;
char *buffer;
/* Find out the string length */
ret = RegQueryValueEx(regkey, "InstallDir", NULL, &type, NULL, &size);
if (ret == ERROR_SUCCESS && type == REG_SZ) {
buffer = snewn(size + 20, char);
ret = RegQueryValueEx(regkey, "InstallDir", NULL,
&type, (LPBYTE)buffer, &size);
if (ret == ERROR_SUCCESS && type == REG_SZ) {
strcat (buffer, "\\bin");
if(p_AddDllDirectory) {
/* Add MIT Kerberos' path to the DLL search path,
* it loads its own DLLs further down the road */
wchar_t *dllPath =
dup_mb_to_wc(DEFAULT_CODEPAGE, 0, buffer);
p_AddDllDirectory(dllPath);
sfree(dllPath);
}
strcat (buffer, "\\gssapi"MIT_KERB_SUFFIX".dll");
module = LoadLibraryEx (buffer, NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32 |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_USER_DIRS);
/*
* The MIT Kerberos DLL suffers an internal segfault
* for some reason if you unload and reload one within
* the same process. So, make sure that after we load
* this library, we never free it.
*
* Or rather: after we've loaded it once, if any
* _further_ load returns the same module handle, we
* immediately free it again (to prevent the Windows
* API's internal reference count growing without
* bound). But on the other hand we never free it in
* ssh_gss_cleanup.
*/
if (library_is_in_never_unload_tree(module))
FreeLibrary(module);
add_library_to_never_unload_tree(module);
HKEY regkey = open_regkey_ro(HKEY_LOCAL_MACHINE,
"SOFTWARE\\MIT\\Kerberos");
if (regkey) {
char *installdir = get_reg_sz(regkey, "InstallDir");
if (installdir) {
char *bindir = dupcat(installdir, "\\bin");
if(p_AddDllDirectory) {
/* Add MIT Kerberos' path to the DLL search path,
* it loads its own DLLs further down the road */
wchar_t *dllPath = dup_mb_to_wc(DEFAULT_CODEPAGE, 0, bindir);
p_AddDllDirectory(dllPath);
sfree(dllPath);
}
sfree(buffer);
char *dllfile = dupcat(bindir, "\\gssapi"MIT_KERB_SUFFIX".dll");
module = LoadLibraryEx(dllfile, NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32 |
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR |
LOAD_LIBRARY_SEARCH_USER_DIRS);
/*
* The MIT Kerberos DLL suffers an internal segfault for
* some reason if you unload and reload one within the
* same process. So, make sure that after we load this
* library, we never free it.
*
* Or rather: after we've loaded it once, if any _further_
* load returns the same module handle, we immediately
* free it again (to prevent the Windows API's internal
* reference count growing without bound). But on the
* other hand we never free it in ssh_gss_cleanup.
*/
if (library_is_in_never_unload_tree(module))
FreeLibrary(module);
add_library_to_never_unload_tree(module);
sfree(dllfile);
sfree(bindir);
sfree(installdir);
}
RegCloseKey(regkey);
close_regkey(regkey);
}
if (module) {
struct ssh_gss_library *lib =