Replace more ad-hoc growing char buffers with strbuf.

I've fixed a handful of these where I found them in passing, but when
I went systematically looking, there were a lot more that I hadn't
found!

A particular highlight of this collection is the code that formats
Windows clipboard data in RTF, which was absolutely crying out for
strbuf_catf, and now it's got it.
This commit is contained in:
Simon Tatham 2019-02-11 06:58:07 +00:00
Родитель e3e4315033
Коммит d07d7d66f6
13 изменённых файлов: 194 добавлений и 311 удалений

2
Recipe
Просмотреть файл

@ -395,7 +395,7 @@ testcrypt : [C] testcrypt SSHCRYPTO sshprng sshprime marshal utils
+ memory tree234 winmiscs
testsc : [UT] testsc SSHCRYPTO marshal utils memory tree234 wildcard
+ sshmac uxutils
testzlib : [UT] testzlib sshzlib memory
testzlib : [UT] testzlib sshzlib utils marshal memory
uppity : [UT] uxserver SSHSERVER UXMISC uxsignal uxnoise uxgss uxnogtk
+ uxpty uxsftpserver ux_x11 uxagentsock

Просмотреть файл

@ -563,10 +563,7 @@ int cmdline_process_param(const char *p, char *value,
}
if (!strcmp(p, "-m")) {
const char *filename;
char *command;
int cmdlen, cmdsize;
FILE *fp;
int c, d;
RETURN(2);
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
@ -574,29 +571,24 @@ int cmdline_process_param(const char *p, char *value,
filename = value;
cmdlen = cmdsize = 0;
command = NULL;
fp = fopen(filename, "r");
if (!fp) {
cmdline_error("unable to open command file \"%s\"", filename);
return ret;
}
do {
c = fgetc(fp);
d = c;
if (c == EOF)
d = 0;
if (cmdlen >= cmdsize) {
cmdsize = cmdlen + 512;
command = sresize(command, cmdsize, char);
}
command[cmdlen++] = d;
} while (c != EOF);
strbuf *command = strbuf_new();
char readbuf[4096];
while (1) {
size_t nread = fread(readbuf, 1, sizeof(readbuf), fp);
if (nread == 0)
break;
put_data(command, readbuf, nread);
}
fclose(fp);
conf_set_str(conf, CONF_remote_cmd, command);
conf_set_str(conf, CONF_remote_cmd, command->s);
conf_set_str(conf, CONF_remote_cmd2, "");
conf_set_bool(conf, CONF_nopty, true); /* command => no terminal */
sfree(command);
strbuf_free(command);
}
if (!strcmp(p, "-P")) {
RETURN(2);

Просмотреть файл

@ -1084,8 +1084,7 @@ struct openssh_new_key {
/* This too points to a position within keyblob */
ptrlen private;
unsigned char *keyblob;
int keyblob_len, keyblob_size;
strbuf *keyblob;
};
static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
@ -1103,8 +1102,7 @@ static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
unsigned key_index;
ret = snew(struct openssh_new_key);
ret->keyblob = NULL;
ret->keyblob_len = ret->keyblob_size = 0;
ret->keyblob = strbuf_new();
fp = f_open(filename, "r", false);
if (!fp) {
@ -1153,14 +1151,7 @@ static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
goto error;
}
if (ret->keyblob_len + len > ret->keyblob_size) {
ret->keyblob_size = ret->keyblob_len + len + 256;
ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
unsigned char);
}
memcpy(ret->keyblob + ret->keyblob_len, out, len);
ret->keyblob_len += len;
put_data(ret->keyblob, out, len);
smemclr(out, sizeof(out));
}
@ -1175,12 +1166,12 @@ static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
fclose(fp);
fp = NULL;
if (ret->keyblob_len == 0 || !ret->keyblob) {
if (ret->keyblob->len == 0 || !ret->keyblob) {
errmsg = "key body not present";
goto error;
}
BinarySource_BARE_INIT(src, ret->keyblob, ret->keyblob_len);
BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(ret->keyblob));
if (strcmp(get_asciz(src), "openssh-key-v1") != 0) {
errmsg = "new-style OpenSSH magic number missing\n";
@ -1288,10 +1279,7 @@ static struct openssh_new_key *load_openssh_new_key(const Filename *filename,
}
smemclr(base64_bit, sizeof(base64_bit));
if (ret) {
if (ret->keyblob) {
smemclr(ret->keyblob, ret->keyblob_size);
sfree(ret->keyblob);
}
strbuf_free(ret->keyblob);
smemclr(ret, sizeof(*ret));
sfree(ret);
}
@ -1308,8 +1296,7 @@ static bool openssh_new_encrypted(const Filename *filename)
if (!key)
return false;
ret = (key->cipher != ON_E_NONE);
smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
strbuf_free(key->keyblob);
smemclr(key, sizeof(*key));
sfree(key);
return ret;
@ -1483,8 +1470,7 @@ static ssh2_userkey *openssh_new_read(
ssh_key_free(retkey->key);
sfree(retkey);
}
smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
strbuf_free(key->keyblob);
smemclr(key, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
@ -1714,8 +1700,7 @@ static bool openssh_auto_write(
struct sshcom_key {
char comment[256]; /* allowing any length is overkill */
unsigned char *keyblob;
int keyblob_len, keyblob_size;
strbuf *keyblob;
};
static struct sshcom_key *load_sshcom_key(const Filename *filename,
@ -1733,8 +1718,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
ret = snew(struct sshcom_key);
ret->comment[0] = '\0';
ret->keyblob = NULL;
ret->keyblob_len = ret->keyblob_size = 0;
ret->keyblob = strbuf_new();
fp = f_open(filename, "r", false);
if (!fp) {
@ -1831,14 +1815,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
goto error;
}
if (ret->keyblob_len + len > ret->keyblob_size) {
ret->keyblob_size = ret->keyblob_len + len + 256;
ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
unsigned char);
}
memcpy(ret->keyblob + ret->keyblob_len, out, len);
ret->keyblob_len += len;
put_data(ret->keyblob, out, len);
}
p++;
@ -1849,7 +1826,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
line = NULL;
}
if (ret->keyblob_len == 0 || !ret->keyblob) {
if (ret->keyblob->len == 0) {
errmsg = "key body not present";
goto error;
}
@ -1868,10 +1845,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
line = NULL;
}
if (ret) {
if (ret->keyblob) {
smemclr(ret->keyblob, ret->keyblob_size);
sfree(ret->keyblob);
}
strbuf_free(ret->keyblob);
smemclr(ret, sizeof(*ret));
sfree(ret);
}
@ -1890,7 +1864,7 @@ static bool sshcom_encrypted(const Filename *filename, char **comment)
if (!key)
goto done;
BinarySource_BARE_INIT(src, key->keyblob, key->keyblob_len);
BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(key->keyblob));
if (get_uint32(src) != SSHCOM_MAGIC_NUMBER)
goto done; /* key is invalid */
@ -1905,8 +1879,7 @@ static bool sshcom_encrypted(const Filename *filename, char **comment)
done:
if (key) {
*comment = dupstr(key->comment);
smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
strbuf_free(key->keyblob);
smemclr(key, sizeof(*key));
sfree(key);
} else {
@ -1983,7 +1956,7 @@ static ssh2_userkey *sshcom_read(
if (!key)
return NULL;
BinarySource_BARE_INIT(src, key->keyblob, key->keyblob_len);
BinarySource_BARE_INIT_PL(src, ptrlen_from_strbuf(key->keyblob));
if (get_uint32(src) != SSHCOM_MAGIC_NUMBER) {
errmsg = "key does not begin with magic number";
@ -2158,8 +2131,7 @@ static ssh2_userkey *sshcom_read(
if (blob) {
strbuf_free(blob);
}
smemclr(key->keyblob, key->keyblob_size);
sfree(key->keyblob);
strbuf_free(key->keyblob);
smemclr(key, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;

Просмотреть файл

@ -450,14 +450,11 @@ static Filename *xlatlognam(Filename *src, char *hostname, int port,
{
char buf[32], *bufp;
int size;
char *buffer;
int buflen, bufsize;
strbuf *buffer;
const char *s;
Filename *ret;
bufsize = FILENAME_MAX;
buffer = snewn(bufsize, char);
buflen = 0;
buffer = strbuf_new();
s = filename_to_str(src);
while (*s) {
@ -504,20 +501,15 @@ static Filename *xlatlognam(Filename *src, char *hostname, int port,
buf[0] = *s++;
size = 1;
}
if (bufsize <= buflen + size) {
bufsize = (buflen + size) * 5 / 4 + 512;
buffer = sresize(buffer, bufsize, char);
}
while (size-- > 0) {
char c = *bufp++;
if (sanitise)
c = filename_char_sanitise(c);
buffer[buflen++] = c;
put_byte(buffer, c);
}
}
buffer[buflen] = '\0';
ret = filename_from_str(buffer);
sfree(buffer);
ret = filename_from_str(buffer->s);
strbuf_free(buffer);
return ret;
}

50
pscp.c
Просмотреть файл

@ -1096,7 +1096,7 @@ int scp_sink_init(void)
#define SCP_SINK_RETRY 4 /* not an action; just try again */
struct scp_sink_action {
int action; /* FILE, DIR, ENDDIR */
char *buf; /* will need freeing after use */
strbuf *buf; /* will need freeing after use */
char *name; /* filename or dirname (not ENDDIR) */
long permissions; /* access permissions (not ENDDIR) */
uint64_t size; /* file size (not ENDDIR) */
@ -1327,8 +1327,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
act->action = SCP_SINK_RETRY;
} else {
act->action = SCP_SINK_DIR;
act->buf = dupstr(stripslashes(fname, false));
act->name = act->buf;
act->buf->len = 0;
put_asciz(act->buf, stripslashes(fname, false));
act->name = act->buf->s;
act->size = 0; /* duhh, it's a directory */
act->permissions = 07777 & attrs.permissions;
if (scp_sftp_preserve &&
@ -1346,8 +1347,9 @@ int scp_get_sink_action(struct scp_sink_action *act)
* It's a file. Return SCP_SINK_FILE.
*/
act->action = SCP_SINK_FILE;
act->buf = dupstr(stripslashes(fname, false));
act->name = act->buf;
act->buf->len = 0;
put_asciz(act->buf, stripslashes(fname, false));
act->name = act->buf->s;
if (attrs.flags & SSH_FILEXFER_ATTR_SIZE) {
act->size = attrs.size;
} else
@ -1369,46 +1371,38 @@ int scp_get_sink_action(struct scp_sink_action *act)
} else {
bool done = false;
int i, bufsize;
int action;
char ch;
act->settime = false;
act->buf = NULL;
bufsize = 0;
act->buf->len = 0;
while (!done) {
if (!ssh_scp_recv(&ch, 1))
return 1;
if (ch == '\n')
bump("Protocol error: Unexpected newline");
i = 0;
action = ch;
do {
if (!ssh_scp_recv(&ch, 1))
bump("Lost connection");
if (i >= bufsize) {
bufsize = i + 128;
act->buf = sresize(act->buf, bufsize, char);
}
act->buf[i++] = ch;
put_byte(act->buf, ch);
} while (ch != '\n');
act->buf[i - 1] = '\0';
switch (action) {
case '\01': /* error */
with_stripctrl(san, act->buf)
with_stripctrl(san, act->buf->s)
tell_user(stderr, "%s", san);
errs++;
continue; /* go round again */
case '\02': /* fatal error */
with_stripctrl(san, act->buf)
with_stripctrl(san, act->buf->s)
bump("%s", san);
case 'E':
backend_send(backend, "", 1);
act->action = SCP_SINK_ENDDIR;
return 0;
case 'T':
if (sscanf(act->buf, "%lu %*d %lu %*d",
if (sscanf(act->buf->s, "%lu %*d %lu %*d",
&act->mtime, &act->atime) == 2) {
act->settime = true;
backend_send(backend, "", 1);
@ -1438,10 +1432,11 @@ int scp_get_sink_action(struct scp_sink_action *act)
* SCP_SINK_DIR.
*/
{
if (sscanf(act->buf, "%lo %"SCNu64" %n", &act->permissions,
int i;
if (sscanf(act->buf->s, "%lo %"SCNu64" %n", &act->permissions,
&act->size, &i) != 2)
bump("Protocol error: Illegal file descriptor format");
act->name = act->buf + i;
act->name = act->buf->s + i;
return 0;
}
}
@ -1758,13 +1753,17 @@ static void sink(const char *targ, const char *src)
bump("%s: Not a directory", targ);
scp_sink_init();
struct scp_sink_action act;
act.buf = strbuf_new();
while (1) {
struct scp_sink_action act;
if (scp_get_sink_action(&act))
return;
goto out;
if (act.action == SCP_SINK_ENDDIR)
return;
goto out;
if (act.action == SCP_SINK_RETRY)
continue;
@ -1889,7 +1888,7 @@ static void sink(const char *targ, const char *src)
if (scp_accept_filexfer()) {
sfree(destfname);
close_wfile(f);
return;
goto out;
}
stat_bytes = 0;
@ -1947,8 +1946,9 @@ static void sink(const char *targ, const char *src)
(void) scp_finish_filerecv();
sfree(stat_name);
sfree(destfname);
sfree(act.buf);
}
out:
strbuf_free(act.buf);
}
/*

Просмотреть файл

@ -490,32 +490,19 @@ static bool read_header(FILE * fp, char *header)
static char *read_body(FILE * fp)
{
char *text;
int len;
int size;
int c;
size = 128;
text = snewn(size, char);
len = 0;
text[len] = '\0';
strbuf *buf = strbuf_new();
while (1) {
c = fgetc(fp);
int c = fgetc(fp);
if (c == '\r' || c == '\n' || c == EOF) {
if (c != EOF) {
c = fgetc(fp);
if (c != '\r' && c != '\n')
ungetc(c, fp);
}
return text;
return strbuf_to_str(buf);
}
if (len + 1 >= size) {
size += 128;
text = sresize(text, size, char);
}
text[len++] = c;
text[len] = '\0';
put_byte(buf, c);
}
}
@ -847,8 +834,7 @@ bool rfc4716_loadpub(FILE *fp, char **algorithm,
const char *error;
char *line, *colon, *value;
char *comment = NULL;
unsigned char *pubblob = NULL;
int pubbloblen, pubblobsize;
strbuf *pubblob = NULL;
char base64in[4];
unsigned char base64out[3];
int base64bytes;
@ -909,9 +895,7 @@ bool rfc4716_loadpub(FILE *fp, char **algorithm,
* Now line contains the initial line of base64 data. Loop round
* while it still does contain base64.
*/
pubblobsize = 4096;
pubblob = snewn(pubblobsize, unsigned char);
pubbloblen = 0;
pubblob = strbuf_new();
base64bytes = 0;
while (line && line[0] != '-') {
char *p;
@ -919,12 +903,7 @@ bool rfc4716_loadpub(FILE *fp, char **algorithm,
base64in[base64bytes++] = *p;
if (base64bytes == 4) {
int n = base64_decode_atom(base64in, base64out);
if (pubbloblen + n > pubblobsize) {
pubblobsize = (pubbloblen + n) * 5 / 4 + 1024;
pubblob = sresize(pubblob, pubblobsize, unsigned char);
}
memcpy(pubblob + pubbloblen, base64out, n);
pubbloblen += n;
put_data(pubblob, base64out, n);
base64bytes = 0;
}
}
@ -946,29 +925,30 @@ bool rfc4716_loadpub(FILE *fp, char **algorithm,
* return the key algorithm string too, so look for that at the
* start of the public blob.
*/
if (pubbloblen < 4) {
if (pubblob->len < 4) {
error = "not enough data in SSH-2 public key file";
goto error;
}
alglen = toint(GET_32BIT_MSB_FIRST(pubblob));
if (alglen < 0 || alglen > pubbloblen-4) {
alglen = toint(GET_32BIT_MSB_FIRST(pubblob->u));
if (alglen < 0 || alglen > pubblob->len-4) {
error = "invalid algorithm prefix in SSH-2 public key file";
goto error;
}
if (algorithm)
*algorithm = dupprintf("%.*s", alglen, pubblob+4);
*algorithm = dupprintf("%.*s", alglen, pubblob->s+4);
if (commentptr)
*commentptr = comment;
else
sfree(comment);
put_data(bs, pubblob, pubbloblen);
sfree(pubblob);
put_datapl(bs, ptrlen_from_strbuf(pubblob));
strbuf_free(pubblob);
return true;
error:
sfree(line);
sfree(comment);
sfree(pubblob);
if (pubblob)
strbuf_free(pubblob);
if (errorstr)
*errorstr = error;
return false;

Просмотреть файл

@ -28,8 +28,7 @@ struct ssh_verstring_state {
int remote_bugs;
char prefix[PREFIX_MAXLEN];
char *impl_name;
char *vstring;
size_t vslen, vstrsize;
strbuf *vstring;
char *protoversion;
const char *softwareversion;
@ -93,6 +92,7 @@ BinaryPacketProtocol *ssh_verstring_new(
s->our_protoversion = dupstr(protoversion);
s->receiver = rcv;
s->impl_name = dupstr(impl_name);
s->vstring = strbuf_new();
/*
* We send our version string early if we can. But if it includes
@ -114,7 +114,7 @@ void ssh_verstring_free(BinaryPacketProtocol *bpp)
container_of(bpp, struct ssh_verstring_state, bpp);
conf_free(s->conf);
sfree(s->impl_name);
sfree(s->vstring);
strbuf_free(s->vstring);
sfree(s->protoversion);
sfree(s->our_vstring);
sfree(s->our_protoversion);
@ -271,12 +271,9 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp)
s->found_prefix = true;
/*
* Start a buffer to store the full greeting line.
* Copy the greeting line so far into vstring.
*/
s->vstrsize = s->prefix_wanted.len + 16;
s->vstring = snewn(s->vstrsize, char);
memcpy(s->vstring, s->prefix_wanted.ptr, s->prefix_wanted.len);
s->vslen = s->prefix_wanted.len;
put_data(s->vstring, s->prefix_wanted.ptr, s->prefix_wanted.len);
/*
* Now read the rest of the greeting line.
@ -292,30 +289,23 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp)
data.len = nl - (char *)data.ptr + 1;
}
if (s->vslen >= s->vstrsize - 1 ||
data.len >= s->vstrsize - 1 - s->vslen) {
s->vstrsize = (s->vslen + data.len) * 5 / 4 + 32;
s->vstring = sresize(s->vstring, s->vstrsize, char);
}
memcpy(s->vstring + s->vslen, data.ptr, data.len);
s->vslen += data.len;
put_datapl(s->vstring, data);
bufchain_consume(s->bpp.in_raw, data.len);
ssh_check_frozen(s->bpp.ssh);
} while (s->vstring[s->vslen-1] != '\012');
} while (s->vstring->s[s->vstring->len-1] != '\012');
/*
* Trim \r and \n from the version string, and replace them with
* a NUL terminator.
*/
while (s->vslen > 0 &&
(s->vstring[s->vslen-1] == '\r' ||
s->vstring[s->vslen-1] == '\n'))
s->vslen--;
s->vstring[s->vslen] = '\0';
while (s->vstring->len > 0 &&
(s->vstring->s[s->vstring->len-1] == '\r' ||
s->vstring->s[s->vstring->len-1] == '\n'))
s->vstring->len--;
s->vstring->s[s->vstring->len] = '\0';
bpp_logevent("Remote version: %s", s->vstring);
bpp_logevent("Remote version: %s", s->vstring->s);
/*
* Pick out the protocol version and software version. The former
@ -324,7 +314,7 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp)
* tail of s->vstring, so it doesn't need to be allocated.
*/
{
const char *pv_start = s->vstring + s->prefix_wanted.len;
const char *pv_start = s->vstring->s + s->prefix_wanted.len;
int pv_len = strcspn(pv_start, "-");
s->protoversion = dupprintf("%.*s", pv_len, pv_start);
s->softwareversion = pv_start + pv_len;
@ -614,7 +604,7 @@ const char *ssh_verstring_get_remote(BinaryPacketProtocol *bpp)
{
struct ssh_verstring_state *s =
container_of(bpp, struct ssh_verstring_state, bpp);
return s->vstring;
return s->vstring->s;
}
const char *ssh_verstring_get_local(BinaryPacketProtocol *bpp)

Просмотреть файл

@ -342,8 +342,7 @@ static void lz77_compress(struct LZ77Context *ctx,
*/
struct Outbuf {
unsigned char *outbuf;
int outlen, outsize;
strbuf *outbuf;
unsigned long outbits;
int noutbits;
bool firstblock;
@ -355,11 +354,7 @@ static void outbits(struct Outbuf *out, unsigned long bits, int nbits)
out->outbits |= bits << out->noutbits;
out->noutbits += nbits;
while (out->noutbits >= 8) {
if (out->outlen >= out->outsize) {
out->outsize = out->outlen + 64;
out->outbuf = sresize(out->outbuf, out->outsize, unsigned char);
}
out->outbuf[out->outlen++] = (unsigned char) (out->outbits & 0xFF);
put_byte(out->outbuf, out->outbits & 0xFF);
out->outbits >>= 8;
out->noutbits -= 8;
}
@ -589,6 +584,7 @@ ssh_compressor *zlib_compress_init(void)
comp->ectx.match = zlib_match;
out = snew(struct Outbuf);
out->outbuf = NULL;
out->outbits = out->noutbits = 0;
out->firstblock = true;
comp->ectx.userdata = out;
@ -600,7 +596,10 @@ void zlib_compress_cleanup(ssh_compressor *sc)
{
struct ssh_zlib_compressor *comp =
container_of(sc, struct ssh_zlib_compressor, sc);
sfree(comp->ectx.userdata);
struct Outbuf *out = (struct Outbuf *)comp->ectx.userdata;
if (out->outbuf)
strbuf_free(out->outbuf);
sfree(out);
sfree(comp->ectx.ictx);
sfree(comp);
}
@ -615,8 +614,8 @@ void zlib_compress_block(ssh_compressor *sc,
struct Outbuf *out = (struct Outbuf *) comp->ectx.userdata;
bool in_block;
out->outbuf = NULL;
out->outlen = out->outsize = 0;
assert(!out->outbuf);
out->outbuf = strbuf_new();
/*
* If this is the first block, output the Zlib (RFC1950) header
@ -678,13 +677,14 @@ void zlib_compress_block(ssh_compressor *sc,
* at least a given length, do so by emitting further empty static
* blocks.
*/
while (out->outlen < minlen) {
while (out->outbuf->len < minlen) {
outbits(out, 0, 7); /* close block */
outbits(out, 2, 3); /* open new static block */
}
*outblock = out->outbuf;
*outlen = out->outlen;
*outlen = out->outbuf->len;
*outblock = (unsigned char *)strbuf_to_str(out->outbuf);
out->outbuf = NULL;
}
/* ----------------------------------------------------------------------
@ -855,8 +855,7 @@ struct zlib_decompress_ctx {
int nbits;
unsigned char window[WINSIZE];
int winpos;
unsigned char *outblk;
int outlen, outsize;
strbuf *outblk;
ssh_decompressor dc;
};
@ -878,6 +877,7 @@ ssh_decompressor *zlib_decompress_init(void)
dctx->bits = 0;
dctx->nbits = 0;
dctx->winpos = 0;
dctx->outblk = NULL;
dctx->dc.vt = &ssh_zlib;
return &dctx->dc;
@ -896,6 +896,8 @@ void zlib_decompress_cleanup(ssh_decompressor *dc)
zlib_freetable(&dctx->lenlentable);
zlib_freetable(&dctx->staticlentable);
zlib_freetable(&dctx->staticdisttable);
if (dctx->outblk)
strbuf_free(dctx->outblk);
sfree(dctx);
}
@ -935,11 +937,7 @@ static void zlib_emit_char(struct zlib_decompress_ctx *dctx, int c)
{
dctx->window[dctx->winpos] = c;
dctx->winpos = (dctx->winpos + 1) & (WINSIZE - 1);
if (dctx->outlen >= dctx->outsize) {
dctx->outsize = dctx->outlen + 512;
dctx->outblk = sresize(dctx->outblk, dctx->outsize, unsigned char);
}
dctx->outblk[dctx->outlen++] = c;
put_byte(dctx->outblk, c);
}
#define EATBITS(n) ( dctx->nbits -= (n), dctx->bits >>= (n) )
@ -956,9 +954,8 @@ bool zlib_decompress_block(ssh_decompressor *dc,
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
};
dctx->outblk = snewn(256, unsigned char);
dctx->outsize = 256;
dctx->outlen = 0;
assert(!dctx->outblk);
dctx->outblk = strbuf_new();
while (len > 0 || dctx->nbits > 0) {
while (dctx->nbits < 24 && len > 0) {
@ -1185,13 +1182,13 @@ bool zlib_decompress_block(ssh_decompressor *dc,
}
finished:
*outblock = dctx->outblk;
*outlen = dctx->outlen;
*outlen = dctx->outblk->len;
*outblock = (unsigned char *)strbuf_to_str(dctx->outblk);
dctx->outblk = NULL;
return true;
decode_error:
sfree(dctx->outblk);
*outblock = dctx->outblk = NULL;
*outblock = NULL;
*outlen = 0;
return false;
}

Просмотреть файл

@ -184,9 +184,8 @@ struct Telnet {
bool activated;
size_t bufsize;
bool in_synch;
int sb_opt, sb_len;
unsigned char *sb_buf;
int sb_size;
int sb_opt;
strbuf *sb_buf;
bool session_started;
enum {
@ -363,7 +362,7 @@ static void process_subneg(Telnet *telnet)
switch (telnet->sb_opt) {
case TELOPT_TSPEED:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
if (telnet->sb_buf->len == 1 && telnet->sb_buf->u[0] == TELQUAL_SEND) {
char *termspeed = conf_get_str(telnet->conf, CONF_termspeed);
b = snewn(20 + strlen(termspeed), unsigned char);
b[0] = IAC;
@ -382,7 +381,7 @@ static void process_subneg(Telnet *telnet)
logevent(telnet->logctx, "server:\tSB TSPEED <something weird>");
break;
case TELOPT_TTYPE:
if (telnet->sb_len == 1 && telnet->sb_buf[0] == TELQUAL_SEND) {
if (telnet->sb_buf->len == 1 && telnet->sb_buf->u[0] == TELQUAL_SEND) {
char *termtype = conf_get_str(telnet->conf, CONF_termtype);
b = snewn(20 + strlen(termtype), unsigned char);
b[0] = IAC;
@ -405,8 +404,8 @@ static void process_subneg(Telnet *telnet)
break;
case TELOPT_OLD_ENVIRON:
case TELOPT_NEW_ENVIRON:
p = telnet->sb_buf;
q = p + telnet->sb_len;
p = telnet->sb_buf->u;
q = p + telnet->sb_buf->len;
if (p < q && *p == TELQUAL_SEND) {
p++;
logeventf(telnet->logctx, "server:\tSB %s SEND",
@ -581,7 +580,7 @@ static void do_telnet_read(Telnet *telnet, const char *buf, size_t len)
break;
case SEENSB:
telnet->sb_opt = c;
telnet->sb_len = 0;
telnet->sb_buf->len = 0;
telnet->state = SUBNEGOT;
break;
case SUBNEGOT:
@ -589,12 +588,7 @@ static void do_telnet_read(Telnet *telnet, const char *buf, size_t len)
telnet->state = SUBNEG_IAC;
else {
subneg_addchar:
if (telnet->sb_len >= telnet->sb_size) {
telnet->sb_size += SB_DELTA;
telnet->sb_buf = sresize(telnet->sb_buf, telnet->sb_size,
unsigned char);
}
telnet->sb_buf[telnet->sb_len++] = c;
put_byte(telnet->sb_buf, c);
telnet->state = SUBNEGOT; /* in case we came here by goto */
}
break;
@ -704,8 +698,7 @@ static const char *telnet_init(Seat *seat, Backend **backend_handle,
telnet->echoing = true;
telnet->editing = true;
telnet->activated = false;
telnet->sb_buf = NULL;
telnet->sb_size = 0;
telnet->sb_buf = strbuf_new();
telnet->seat = seat;
telnet->logctx = logctx;
telnet->term_width = conf_get_int(telnet->conf, CONF_width);
@ -791,7 +784,7 @@ static void telnet_free(Backend *be)
{
Telnet *telnet = container_of(be, Telnet, backend);
sfree(telnet->sb_buf);
strbuf_free(telnet->sb_buf);
if (telnet->s)
sk_close(telnet->s);
if (telnet->pinger)

Просмотреть файл

@ -679,32 +679,21 @@ int main(int argc, char **argv)
!strcmp(p, "-no-sanitize-stderr")) {
sanitise_stderr = FORCE_OFF;
} else if (*p != '-') {
char *command;
int cmdlen, cmdsize;
cmdlen = cmdsize = 0;
command = NULL;
strbuf *cmdbuf = strbuf_new();
while (argc) {
while (*p) {
if (cmdlen >= cmdsize) {
cmdsize = cmdlen + 512;
command = sresize(command, cmdsize, char);
}
command[cmdlen++]=*p++;
}
if (cmdlen >= cmdsize) {
cmdsize = cmdlen + 512;
command = sresize(command, cmdsize, char);
}
command[cmdlen++]=' '; /* always add trailing space */
if (--argc) p = *++argv;
while (argc > 0) {
if (cmdbuf->len > 0)
put_byte(cmdbuf, ' '); /* add space separator */
put_datapl(cmdbuf, ptrlen_from_asciz(p));
if (--argc > 0)
p = *++argv;
}
if (cmdlen) command[--cmdlen]='\0';
/* change trailing blank to NUL */
conf_set_str(conf, CONF_remote_cmd, command);
conf_set_str(conf, CONF_remote_cmd, cmdbuf->s);
conf_set_str(conf, CONF_remote_cmd2, "");
conf_set_bool(conf, CONF_nopty, true); /* command => no tty */
strbuf_free(cmdbuf);
break; /* done with cmdline */
} else {
fprintf(stderr, "plink: unknown option \"%s\"\n", p);

Просмотреть файл

@ -548,34 +548,33 @@ bool enum_settings_next(settings_e *handle, strbuf *out)
{
struct dirent *de;
struct stat st;
char *fullpath;
int maxlen, thislen, len;
strbuf *fullpath;
if (!handle->dp)
return NULL;
fullpath = make_filename(INDEX_SESSIONDIR, NULL);
maxlen = len = strlen(fullpath);
fullpath = strbuf_new();
char *sessiondir = make_filename(INDEX_SESSIONDIR, NULL);
put_datapl(fullpath, ptrlen_from_asciz(sessiondir));
sfree(sessiondir);
put_byte(fullpath, '/');
size_t baselen = fullpath->len;
while ( (de = readdir(handle->dp)) != NULL ) {
thislen = len + 1 + strlen(de->d_name);
if (maxlen < thislen) {
maxlen = thislen;
fullpath = sresize(fullpath, maxlen+1, char);
}
fullpath[len] = '/';
strncpy(fullpath+len+1, de->d_name, thislen - (len+1));
fullpath[thislen] = '\0';
fullpath->len = baselen;
put_datapl(fullpath, ptrlen_from_asciz(de->d_name));
if (stat(fullpath, &st) < 0 || !S_ISREG(st.st_mode))
if (stat(fullpath->s, &st) < 0 || !S_ISREG(st.st_mode))
continue; /* try another one */
decode_session_filename(de->d_name, out);
sfree(fullpath);
strbuf_free(fullpath);
return true;
}
sfree(fullpath);
strbuf_free(fullpath);
return false;
}

Просмотреть файл

@ -4924,11 +4924,10 @@ static void wintw_clip_write(
if (conf_get_bool(conf, CONF_rtf_paste)) {
wchar_t unitab[256];
char *rtf = NULL;
strbuf *rtf = strbuf_new();
unsigned char *tdata = (unsigned char *)lock2;
wchar_t *udata = (wchar_t *)lock;
int rtflen = 0, uindex = 0, tindex = 0;
int rtfsize = 0;
int uindex = 0, tindex = 0;
int multilen, blen, alen, totallen, i;
char before[16], after[4];
int fgcolour, lastfgcolour = -1;
@ -4944,10 +4943,9 @@ static void wintw_clip_write(
get_unitab(CP_ACP, unitab, 0);
rtfsize = 100 + strlen(font->name);
rtf = snewn(rtfsize, char);
rtflen = sprintf(rtf, "{\\rtf1\\ansi\\deff0{\\fonttbl\\f0\\fmodern %s;}\\f0\\fs%d",
font->name, font->height*2);
strbuf_catf(
rtf, "{\\rtf1\\ansi\\deff0{\\fonttbl\\f0\\fmodern %s;}\\f0\\fs%d",
font->name, font->height*2);
/*
* Add colour palette
@ -5028,23 +5026,23 @@ static void wintw_clip_write(
/*
* Finally - Write the colour table
*/
rtf = sresize(rtf, rtfsize + (numcolours * 25), char);
strcat(rtf, "{\\colortbl ;");
rtflen = strlen(rtf);
put_datapl(rtf, PTRLEN_LITERAL("{\\colortbl ;"));
for (i = 0; i < NALLCOLOURS; i++) {
if (palette[i] != 0) {
rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;", defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue);
strbuf_catf(rtf, "\\red%d\\green%d\\blue%d;",
defpal[i].rgbtRed, defpal[i].rgbtGreen,
defpal[i].rgbtBlue);
}
}
if (rgbtree) {
rgbindex *rgbp;
for (i = 0; (rgbp = index234(rgbtree, i)) != NULL; i++)
rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;",
GetRValue(rgbp->ref), GetGValue(rgbp->ref), GetBValue(rgbp->ref));
strbuf_catf(rtf, "\\red%d\\green%d\\blue%d;",
GetRValue(rgbp->ref), GetGValue(rgbp->ref),
GetBValue(rgbp->ref));
}
strcpy(&rtf[rtflen], "}");
rtflen ++;
put_datapl(rtf, PTRLEN_LITERAL("}"));
}
/*
@ -5078,11 +5076,6 @@ static void wintw_clip_write(
* Set text attributes
*/
if (attr) {
if (rtfsize < rtflen + 64) {
rtfsize = rtflen + 512;
rtf = sresize(rtf, rtfsize, char);
}
/*
* Determine foreground and background colours
*/
@ -5165,14 +5158,14 @@ static void wintw_clip_write(
if ((lastfgcolour != fgcolour) || (lastfg != fg)) {
lastfgcolour = fgcolour;
lastfg = fg;
if (fg == -1)
rtflen += sprintf(&rtf[rtflen], "\\cf%d ",
(fgcolour >= 0) ? palette[fgcolour] : 0);
else {
if (fg == -1) {
strbuf_catf(rtf, "\\cf%d ",
(fgcolour >= 0) ? palette[fgcolour] : 0);
} else {
rgbindex rgb, *rgbp;
rgb.ref = fg;
if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL)
rtflen += sprintf(&rtf[rtflen], "\\cf%d ", rgbp->index);
strbuf_catf(rtf, "\\cf%d ", rgbp->index);
}
}
@ -5180,24 +5173,28 @@ static void wintw_clip_write(
lastbgcolour = bgcolour;
lastbg = bg;
if (bg == -1)
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ",
(bgcolour >= 0) ? palette[bgcolour] : 0);
strbuf_catf(rtf, "\\highlight%d ",
(bgcolour >= 0) ? palette[bgcolour] : 0);
else {
rgbindex rgb, *rgbp;
rgb.ref = bg;
if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL)
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", rgbp->index);
strbuf_catf(rtf, "\\highlight%d ", rgbp->index);
}
}
if (lastAttrBold != attrBold) {
lastAttrBold = attrBold;
rtflen += sprintf(&rtf[rtflen], "%s", attrBold ? "\\b " : "\\b0 ");
put_datapl(rtf, attrBold ?
PTRLEN_LITERAL("\\b ") :
PTRLEN_LITERAL("\\b0 "));
}
if (lastAttrUnder != attrUnder) {
lastAttrUnder = attrUnder;
rtflen += sprintf(&rtf[rtflen], "%s", attrUnder ? "\\ul " : "\\ulnone ");
put_datapl(rtf, attrUnder ?
PTRLEN_LITERAL("\\ul ") :
PTRLEN_LITERAL("\\ulnone "));
}
}
@ -5233,42 +5230,35 @@ static void wintw_clip_write(
totallen++;
}
if (rtfsize < rtflen + totallen + 3) {
rtfsize = rtflen + totallen + 512;
rtf = sresize(rtf, rtfsize, char);
}
strcpy(rtf + rtflen, before); rtflen += blen;
put_data(rtf, before, blen);
for (i = 0; i < multilen; i++) {
if (tdata[tindex+i] == '\\' ||
tdata[tindex+i] == '{' ||
tdata[tindex+i] == '}') {
rtf[rtflen++] = '\\';
rtf[rtflen++] = tdata[tindex+i];
put_byte(rtf, '\\');
put_byte(rtf, tdata[tindex+i]);
} else if (tdata[tindex+i] == 0x0D || tdata[tindex+i] == 0x0A) {
rtflen += sprintf(rtf+rtflen, "\\par\r\n");
put_datapl(rtf, PTRLEN_LITERAL("\\par\r\n"));
} else if (tdata[tindex+i] > 0x7E || tdata[tindex+i] < 0x20) {
rtflen += sprintf(rtf+rtflen, "\\'%02x", tdata[tindex+i]);
strbuf_catf(rtf, "\\'%02x", tdata[tindex+i]);
} else {
rtf[rtflen++] = tdata[tindex+i];
put_byte(rtf, tdata[tindex+i]);
}
}
strcpy(rtf + rtflen, after); rtflen += alen;
put_data(rtf, after, alen);
tindex += multilen;
uindex++;
}
rtf[rtflen++] = '}'; /* Terminate RTF stream */
rtf[rtflen++] = '\0';
rtf[rtflen++] = '\0';
put_datapl(rtf, PTRLEN_LITERAL("}\0\0")); /* Terminate RTF stream */
clipdata3 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, rtflen);
clipdata3 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, rtf->len);
if (clipdata3 && (lock3 = GlobalLock(clipdata3)) != NULL) {
memcpy(lock3, rtf, rtflen);
memcpy(lock3, rtf->u, rtf->len);
GlobalUnlock(clipdata3);
}
sfree(rtf);
strbuf_free(rtf);
if (rgbtree) {
rgbindex *rgbp;

Просмотреть файл

@ -352,32 +352,21 @@ int main(int argc, char **argv)
!strcmp(p, "-no-sanitize-stderr")) {
sanitise_stderr = FORCE_OFF;
} else if (*p != '-') {
char *command;
int cmdlen, cmdsize;
cmdlen = cmdsize = 0;
command = NULL;
strbuf *cmdbuf = strbuf_new();
while (argc) {
while (*p) {
if (cmdlen >= cmdsize) {
cmdsize = cmdlen + 512;
command = sresize(command, cmdsize, char);
}
command[cmdlen++]=*p++;
}
if (cmdlen >= cmdsize) {
cmdsize = cmdlen + 512;
command = sresize(command, cmdsize, char);
}
command[cmdlen++]=' '; /* always add trailing space */
if (--argc) p = *++argv;
while (argc > 0) {
if (cmdbuf->len > 0)
put_byte(cmdbuf, ' '); /* add space separator */
put_datapl(cmdbuf, ptrlen_from_asciz(p));
if (--argc > 0)
p = *++argv;
}
if (cmdlen) command[--cmdlen]='\0';
/* change trailing blank to NUL */
conf_set_str(conf, CONF_remote_cmd, command);
conf_set_str(conf, CONF_remote_cmd, cmdbuf->s);
conf_set_str(conf, CONF_remote_cmd2, "");
conf_set_bool(conf, CONF_nopty, true); /* command => no tty */
strbuf_free(cmdbuf);
break; /* done with cmdline */
} else {
fprintf(stderr, "plink: unknown option \"%s\"\n", p);