1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Use the new ctrl_alloc_with_free to clean up a long-standing FIXME in

the session saving code, in which the contents of the edit box giving
the current saved session name was stored in a horrid place with a
fixed length. Now it's dangling off sessionsaver_data as it always
ought to have been, and it's dynamically reallocated to the
appropriate length, and there's a free function that cleans it up at
the end of the dialog's lifetime.

[originally from svn r9923]
This commit is contained in:
Simon Tatham 2013-07-14 10:46:34 +00:00
parent ff09d5379b
commit 7554dd5a9c

View File

@ -557,22 +557,27 @@ static void sshbug_handler(union control *ctrl, void *dlg,
} }
} }
#define SAVEDSESSION_LEN 2048
struct sessionsaver_data { struct sessionsaver_data {
union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton; union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
union control *okbutton, *cancelbutton; union control *okbutton, *cancelbutton;
struct sesslist sesslist; struct sesslist sesslist;
int midsession; int midsession;
char *savedsession; /* the current contents of ssd->editbox */
}; };
static void sessionsaver_data_free(void *ssdv)
{
struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv;
sfree(ssd->savedsession);
sfree(ssd);
}
/* /*
* Helper function to load the session selected in the list box, if * Helper function to load the session selected in the list box, if
* any, as this is done in more than one place below. Returns 0 for * any, as this is done in more than one place below. Returns 0 for
* failure. * failure.
*/ */
static int load_selected_session(struct sessionsaver_data *ssd, static int load_selected_session(struct sessionsaver_data *ssd,
char *savedsession,
void *dlg, Conf *conf, int *maybe_launch) void *dlg, Conf *conf, int *maybe_launch)
{ {
int i = dlg_listbox_index(ssd->listbox, dlg); int i = dlg_listbox_index(ssd->listbox, dlg);
@ -583,17 +588,10 @@ static int load_selected_session(struct sessionsaver_data *ssd,
} }
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings"); isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
load_settings(ssd->sesslist.sessions[i], conf); load_settings(ssd->sesslist.sessions[i], conf);
if (!isdef) { sfree(ssd->savedsession);
strncpy(savedsession, ssd->sesslist.sessions[i], ssd->savedsession = dupstr(isdef ? "" : ssd->sesslist.sessions[i]);
SAVEDSESSION_LEN); if (maybe_launch)
savedsession[SAVEDSESSION_LEN-1] = '\0'; *maybe_launch = !isdef;
if (maybe_launch)
*maybe_launch = TRUE;
} else {
savedsession[0] = '\0';
if (maybe_launch)
*maybe_launch = FALSE;
}
dlg_refresh(NULL, dlg); dlg_refresh(NULL, dlg);
/* Restore the selection, which might have been clobbered by /* Restore the selection, which might have been clobbered by
* changing the value of the edit box. */ * changing the value of the edit box. */
@ -607,33 +605,10 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
Conf *conf = (Conf *)data; Conf *conf = (Conf *)data;
struct sessionsaver_data *ssd = struct sessionsaver_data *ssd =
(struct sessionsaver_data *)ctrl->generic.context.p; (struct sessionsaver_data *)ctrl->generic.context.p;
char *savedsession;
/*
* The first time we're called in a new dialog, we must
* allocate space to store the current contents of the saved
* session edit box (since it must persist even when we switch
* panels, but is not part of the Conf).
*
* FIXME: this is disgusting, and we'd do much better to have
* the persistent storage be dynamically allocated and get rid
* of the arbitrary limit SAVEDSESSION_LEN. To do that would
* require a means of making sure the memory gets freed at the
* appropriate moment.
*/
if (!ssd->editbox) {
savedsession = NULL;
} else if (!dlg_get_privdata(ssd->editbox, dlg)) {
savedsession = (char *)
dlg_alloc_privdata(ssd->editbox, dlg, SAVEDSESSION_LEN);
savedsession[0] = '\0';
} else {
savedsession = dlg_get_privdata(ssd->editbox, dlg);
}
if (event == EVENT_REFRESH) { if (event == EVENT_REFRESH) {
if (ctrl == ssd->editbox) { if (ctrl == ssd->editbox) {
dlg_editbox_set(ctrl, dlg, savedsession); dlg_editbox_set(ctrl, dlg, ssd->savedsession);
} else if (ctrl == ssd->listbox) { } else if (ctrl == ssd->listbox) {
int i; int i;
dlg_update_start(ctrl, dlg); dlg_update_start(ctrl, dlg);
@ -645,14 +620,13 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
} else if (event == EVENT_VALCHANGE) { } else if (event == EVENT_VALCHANGE) {
int top, bottom, halfway, i; int top, bottom, halfway, i;
if (ctrl == ssd->editbox) { if (ctrl == ssd->editbox) {
char *tmp = dlg_editbox_get(ctrl, dlg); sfree(ssd->savedsession);
strncpy(savedsession, tmp, SAVEDSESSION_LEN); ssd->savedsession = dlg_editbox_get(ctrl, dlg);
sfree(tmp);
top = ssd->sesslist.nsessions; top = ssd->sesslist.nsessions;
bottom = -1; bottom = -1;
while (top-bottom > 1) { while (top-bottom > 1) {
halfway = (top+bottom)/2; halfway = (top+bottom)/2;
i = strcmp(savedsession, ssd->sesslist.sessions[halfway]); i = strcmp(ssd->savedsession, ssd->sesslist.sessions[halfway]);
if (i <= 0 ) { if (i <= 0 ) {
top = halfway; top = halfway;
} else { } else {
@ -676,29 +650,25 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
* double-click on the list box _and_ that session * double-click on the list box _and_ that session
* contains a hostname. * contains a hostname.
*/ */
if (load_selected_session(ssd, savedsession, dlg, conf, &mbl) && if (load_selected_session(ssd, dlg, conf, &mbl) &&
(mbl && ctrl == ssd->listbox && conf_launchable(conf))) { (mbl && ctrl == ssd->listbox && conf_launchable(conf))) {
dlg_end(dlg, 1); /* it's all over, and succeeded */ dlg_end(dlg, 1); /* it's all over, and succeeded */
} }
} else if (ctrl == ssd->savebutton) { } else if (ctrl == ssd->savebutton) {
int isdef = !strcmp(savedsession, "Default Settings"); int isdef = !strcmp(ssd->savedsession, "Default Settings");
if (!savedsession[0]) { if (!ssd->savedsession[0]) {
int i = dlg_listbox_index(ssd->listbox, dlg); int i = dlg_listbox_index(ssd->listbox, dlg);
if (i < 0) { if (i < 0) {
dlg_beep(dlg); dlg_beep(dlg);
return; return;
} }
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings"); isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
if (!isdef) { sfree(ssd->savedsession);
strncpy(savedsession, ssd->sesslist.sessions[i], ssd->savedsession = dupstr(isdef ? "" :
SAVEDSESSION_LEN); ssd->sesslist.sessions[i]);
savedsession[SAVEDSESSION_LEN-1] = '\0';
} else {
savedsession[0] = '\0';
}
} }
{ {
char *errmsg = save_settings(savedsession, conf); char *errmsg = save_settings(ssd->savedsession, conf);
if (errmsg) { if (errmsg) {
dlg_error_msg(dlg, errmsg); dlg_error_msg(dlg, errmsg);
sfree(errmsg); sfree(errmsg);
@ -736,8 +706,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
!conf_launchable(conf)) { !conf_launchable(conf)) {
Conf *conf2 = conf_new(); Conf *conf2 = conf_new();
int mbl = FALSE; int mbl = FALSE;
if (!load_selected_session(ssd, savedsession, dlg, if (!load_selected_session(ssd, dlg, conf2, &mbl)) {
conf2, &mbl)) {
dlg_beep(dlg); dlg_beep(dlg);
conf_free(conf2); conf_free(conf2);
return; return;
@ -1256,8 +1225,10 @@ void setup_config_box(struct controlbox *b, int midsession,
char *str; char *str;
ssd = (struct sessionsaver_data *) ssd = (struct sessionsaver_data *)
ctrl_alloc(b, sizeof(struct sessionsaver_data)); ctrl_alloc_with_free(b, sizeof(struct sessionsaver_data),
sessionsaver_data_free);
memset(ssd, 0, sizeof(*ssd)); memset(ssd, 0, sizeof(*ssd));
ssd->savedsession = dupstr("");
ssd->midsession = midsession; ssd->midsession = midsession;
/* /*