mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-25 09:12:24 +00:00
Allocate the SSH specials list dynamically.
The last list we returned is now stored in the main Ssh structure rather than being a static array in ssh_get_specials. The main point of this is that I want to start adding more dynamic things to it, for which I can't predict the array's max length in advance. But also this fixes a conceptual wrongness, in that if a process had more than one Ssh instance in it then their specials arrays would have taken turns occupying the old static array, and although the current single-threaded client code in the GUI front ends wouldn't have minded (it would have read out the contents just once immediately after get_specials returned), it still feels as if it was a bug waiting to happen.
This commit is contained in:
parent
6ef6cb1573
commit
10a48c3591
44
ssh.c
44
ssh.c
@ -954,6 +954,11 @@ struct ssh_tag {
|
|||||||
*/
|
*/
|
||||||
struct ssh_gss_liblist *gsslibs;
|
struct ssh_gss_liblist *gsslibs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The last list returned from get_specials.
|
||||||
|
*/
|
||||||
|
struct telnet_special *specials;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define logevent(s) logevent(ssh->frontend, s)
|
#define logevent(s) logevent(ssh->frontend, s)
|
||||||
@ -11004,6 +11009,7 @@ static const char *ssh_init(void *frontend_handle, void **backend_handle,
|
|||||||
ssh->connshare = NULL;
|
ssh->connshare = NULL;
|
||||||
ssh->attempting_connshare = FALSE;
|
ssh->attempting_connshare = FALSE;
|
||||||
ssh->session_started = FALSE;
|
ssh->session_started = FALSE;
|
||||||
|
ssh->specials = NULL;
|
||||||
|
|
||||||
*backend_handle = ssh;
|
*backend_handle = ssh;
|
||||||
|
|
||||||
@ -11151,6 +11157,7 @@ static void ssh_free(void *handle)
|
|||||||
sfree(ssh->v_s);
|
sfree(ssh->v_s);
|
||||||
sfree(ssh->fullhostname);
|
sfree(ssh->fullhostname);
|
||||||
sfree(ssh->hostkey_str);
|
sfree(ssh->hostkey_str);
|
||||||
|
sfree(ssh->specials);
|
||||||
if (ssh->crcda_ctx) {
|
if (ssh->crcda_ctx) {
|
||||||
crcda_free_context(ssh->crcda_ctx);
|
crcda_free_context(ssh->crcda_ctx);
|
||||||
ssh->crcda_ctx = NULL;
|
ssh->crcda_ctx = NULL;
|
||||||
@ -11364,19 +11371,24 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
|||||||
static const struct telnet_special specials_end[] = {
|
static const struct telnet_special specials_end[] = {
|
||||||
{NULL, TS_EXITMENU}
|
{NULL, TS_EXITMENU}
|
||||||
};
|
};
|
||||||
/* XXX review this length for any changes: */
|
|
||||||
static struct telnet_special ssh_specials[lenof(ssh2_ignore_special) +
|
struct telnet_special *specials = NULL;
|
||||||
lenof(ssh2_rekey_special) +
|
int nspecials = 0, specialsize = 0;
|
||||||
lenof(ssh2_session_specials) +
|
|
||||||
lenof(specials_end)];
|
|
||||||
Ssh ssh = (Ssh) handle;
|
Ssh ssh = (Ssh) handle;
|
||||||
int i = 0;
|
|
||||||
#define ADD_SPECIALS(name) \
|
sfree(ssh->specials);
|
||||||
do { \
|
|
||||||
assert((i + lenof(name)) <= lenof(ssh_specials)); \
|
#define ADD_SPECIALS(name) do \
|
||||||
memcpy(&ssh_specials[i], name, sizeof name); \
|
{ \
|
||||||
i += lenof(name); \
|
int len = lenof(name); \
|
||||||
} while(0)
|
if (nspecials + len > specialsize) { \
|
||||||
|
specialsize = (nspecials + len) * 5 / 4 + 32; \
|
||||||
|
specials = sresize(specials, specialsize, struct telnet_special); \
|
||||||
|
} \
|
||||||
|
memcpy(specials+nspecials, name, len*sizeof(struct telnet_special)); \
|
||||||
|
nspecials += len; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
if (ssh->version == 1) {
|
if (ssh->version == 1) {
|
||||||
/* Don't bother offering IGNORE if we've decided the remote
|
/* Don't bother offering IGNORE if we've decided the remote
|
||||||
@ -11393,9 +11405,13 @@ static const struct telnet_special *ssh_get_specials(void *handle)
|
|||||||
ADD_SPECIALS(ssh2_session_specials);
|
ADD_SPECIALS(ssh2_session_specials);
|
||||||
} /* else we're not ready yet */
|
} /* else we're not ready yet */
|
||||||
|
|
||||||
if (i) {
|
if (nspecials)
|
||||||
ADD_SPECIALS(specials_end);
|
ADD_SPECIALS(specials_end);
|
||||||
return ssh_specials;
|
|
||||||
|
ssh->specials = specials;
|
||||||
|
|
||||||
|
if (nspecials) {
|
||||||
|
return specials;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user