From e0a76971ccfac1393033b28eba9a4e5a08d4ae78 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 28 Feb 2019 20:07:30 +0000 Subject: [PATCH] New array-growing macros: sgrowarray and sgrowarrayn. The idea of these is that they centralise the common idiom along the lines of if (logical_array_len >= physical_array_size) { physical_array_size = logical_array_len * 5 / 4 + 256; array = sresize(array, physical_array_size, ElementType); } which happens at a zillion call sites throughout this code base, with different random choices of the geometric factor and additive constant, sometimes forgetting them completely, and generally doing a lot of repeated work. The new macro sgrowarray(array,size,n) has the semantics: here are the array pointer and its physical size for you to modify, now please ensure that the nth element exists, so I can write into it. And sgrowarrayn(array,size,n,m) is the same except that it ensures that the array has size at least n+m (so sgrowarray is just the special case where m=1). Now that this is a single centralised implementation that will be used everywhere, I've also gone to more effort in the implementation, with careful overflow checks that would have been painful to put at all the previous call sites. This commit also switches over every use of sresize(), apart from a few where I really didn't think it would gain anything. A consequence of that is that a lot of array-size variables have to have their types changed to size_t, because the macros require that (they address-take the size to pass to the underlying function). --- cmdline.c | 8 ++--- dialog.c | 22 +++---------- dialog.h | 12 ++++---- ldisc.c | 5 +-- ldisc.h | 2 +- memory.c | 43 ++++++++++++++++++++++++++ misc.c | 7 ++--- misc.h | 2 +- pscp.c | 14 +++------ psftp.c | 43 +++++++++----------------- putty.h | 1 + puttymem.h | 41 +++++++++++++++++++++++++ sftp.h | 3 +- sftpcommon.c | 10 ++---- ssh.c | 9 ++---- ssh.h | 8 ++--- sshcommon.c | 11 ++----- terminal.c | 42 ++++++++++--------------- terminal.h | 2 +- testcrypt.c | 5 +-- unix/gtkdlg.c | 13 +++----- unix/gtkmain.c | 2 +- unix/uxnet.c | 10 +++--- unix/uxpgnt.c | 8 ++--- unix/uxplink.c | 8 ++--- unix/uxserver.c | 15 +++------ unix/uxsftp.c | 21 +++++-------- unix/uxsftpserver.c | 10 +++--- unix/x11misc.c | 12 +++----- utils.c | 75 ++++++++++++++++++--------------------------- windows/window.c | 16 +++------- windows/winhandl.c | 8 ++--- windows/winmisc.c | 10 +++--- windows/winplink.c | 7 ++--- windows/winsftp.c | 2 +- windows/winstore.c | 3 +- windows/winutils.c | 5 ++- 37 files changed, 236 insertions(+), 279 deletions(-) diff --git a/cmdline.c b/cmdline.c index 083231f1..06f1520f 100644 --- a/cmdline.c +++ b/cmdline.c @@ -35,7 +35,7 @@ struct cmdline_saved_param { }; struct cmdline_saved_param_set { struct cmdline_saved_param *params; - int nsaved, savesize; + size_t nsaved, savesize; }; /* @@ -46,11 +46,7 @@ static struct cmdline_saved_param_set saves[NPRIORITIES]; static void cmdline_save_param(const char *p, const char *value, int pri) { - if (saves[pri].nsaved >= saves[pri].savesize) { - saves[pri].savesize = saves[pri].nsaved + 32; - saves[pri].params = sresize(saves[pri].params, saves[pri].savesize, - struct cmdline_saved_param); - } + sgrowarray(saves[pri].params, saves[pri].savesize, saves[pri].nsaved); saves[pri].params[saves[pri].nsaved].p = dupstr(p); saves[pri].params[saves[pri].nsaved].value = dupstr(value); saves[pri].nsaved++; diff --git a/dialog.c b/dialog.c index d00e2529..c1e0a2b6 100644 --- a/dialog.c +++ b/dialog.c @@ -138,10 +138,7 @@ struct controlset *ctrl_settitle(struct controlbox *b, s->ncontrols = s->ctrlsize = 0; s->ncolumns = 0; /* this is a title! */ s->ctrls = NULL; - if (b->nctrlsets >= b->ctrlsetsize) { - b->ctrlsetsize = b->nctrlsets + 32; - b->ctrlsets = sresize(b->ctrlsets, b->ctrlsetsize,struct controlset *); - } + sgrowarray(b->ctrlsets, b->ctrlsetsize, b->nctrlsets); if (index < b->nctrlsets) memmove(&b->ctrlsets[index+1], &b->ctrlsets[index], (b->nctrlsets-index) * sizeof(*b->ctrlsets)); @@ -170,10 +167,7 @@ struct controlset *ctrl_getset(struct controlbox *b, const char *path, s->ncolumns = 1; s->ncontrols = s->ctrlsize = 0; s->ctrls = NULL; - if (b->nctrlsets >= b->ctrlsetsize) { - b->ctrlsetsize = b->nctrlsets + 32; - b->ctrlsets = sresize(b->ctrlsets, b->ctrlsetsize,struct controlset *); - } + sgrowarray(b->ctrlsets, b->ctrlsetsize, b->nctrlsets); if (index < b->nctrlsets) memmove(&b->ctrlsets[index+1], &b->ctrlsets[index], (b->nctrlsets-index) * sizeof(*b->ctrlsets)); @@ -192,11 +186,8 @@ void *ctrl_alloc_with_free(struct controlbox *b, size_t size, * use smalloc directly. */ p = smalloc(size); - if (b->nfrees >= b->freesize) { - b->freesize = b->nfrees + 32; - b->frees = sresize(b->frees, b->freesize, void *); - b->freefuncs = sresize(b->freefuncs, b->freesize, ctrl_freefn_t); - } + sgrowarray(b->frees, b->freesize, b->nfrees); + b->freefuncs = sresize(b->freefuncs, b->freesize, ctrl_freefn_t); b->frees[b->nfrees] = p; b->freefuncs[b->nfrees] = freefunc; b->nfrees++; @@ -218,10 +209,7 @@ static union control *ctrl_new(struct controlset *s, int type, intorptr context) { union control *c = snew(union control); - if (s->ncontrols >= s->ctrlsize) { - s->ctrlsize = s->ncontrols + 32; - s->ctrls = sresize(s->ctrls, s->ctrlsize, union control *); - } + sgrowarray(s->ctrls, s->ctrlsize, s->ncontrols); s->ctrls[s->ncontrols++] = c; /* * Fill in the standard fields. diff --git a/dialog.h b/dialog.h index 864471bb..6ccda341 100644 --- a/dialog.h +++ b/dialog.h @@ -422,8 +422,8 @@ struct controlset { char *boxname; /* internal short name of controlset */ char *boxtitle; /* title of container box */ int ncolumns; /* current no. of columns at bottom */ - int ncontrols; /* number of `union control' in array */ - int ctrlsize; /* allocated size of array */ + size_t ncontrols; /* number of `union control' in array */ + size_t ctrlsize; /* allocated size of array */ union control **ctrls; /* actual array */ }; @@ -434,11 +434,11 @@ typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */ * controls. */ struct controlbox { - int nctrlsets; /* number of ctrlsets */ - int ctrlsetsize; /* ctrlset size */ + size_t nctrlsets; /* number of ctrlsets */ + size_t ctrlsetsize; /* ctrlset size */ struct controlset **ctrlsets; /* actual array of ctrlsets */ - int nfrees; - int freesize; + size_t nfrees; + size_t freesize; void **frees; /* array of aux data areas to free */ ctrl_freefn_t *freefuncs; /* parallel array of free functions */ }; diff --git a/ldisc.c b/ldisc.c index 0779d142..660e05d6 100644 --- a/ldisc.c +++ b/ldisc.c @@ -291,10 +291,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, bool interactive) /* FALLTHROUGH */ default: /* get to this label from ^V handler */ default_case: - if (ldisc->buflen >= ldisc->bufsiz) { - ldisc->bufsiz = ldisc->buflen + 256; - ldisc->buf = sresize(ldisc->buf, ldisc->bufsiz, char); - } + sgrowarray(ldisc->buf, ldisc->bufsiz, ldisc->buflen); ldisc->buf[ldisc->buflen++] = c; if (ECHOING) pwrite(ldisc, (unsigned char) c); diff --git a/ldisc.h b/ldisc.h index 65a544ad..770b4b05 100644 --- a/ldisc.h +++ b/ldisc.h @@ -20,7 +20,7 @@ struct Ldisc_tag { int protocol, localecho, localedit; char *buf; - int buflen, bufsiz; + size_t buflen, bufsiz; bool quotenext; }; diff --git a/memory.c b/memory.c index 1cb36ed0..448d9bd8 100644 --- a/memory.c +++ b/memory.c @@ -2,6 +2,7 @@ * PuTTY's memory allocation wrappers. */ +#include #include #include @@ -69,3 +70,45 @@ void safefree(void *ptr) #endif } } + +void *safegrowarray(void *ptr, size_t *allocated, size_t eltsize, + size_t oldlen, size_t extralen) +{ + /* The largest value we can safely multiply by eltsize */ + assert(eltsize > 0); + size_t maxsize = (~(size_t)0) / eltsize; + + size_t oldsize = *allocated; + + /* Range-check the input values */ + assert(oldsize <= maxsize); + assert(oldlen <= maxsize); + assert(extralen <= maxsize - oldlen); + + /* If the size is already enough, don't bother doing anything! */ + if (oldsize > oldlen + extralen) + return ptr; + + /* Find out how much we need to grow the array by. */ + size_t increment = (oldlen + extralen) - oldsize; + + /* Invent a new size. We want to grow the array by at least + * 'increment' elements; by at least a fixed number of bytes (to + * get things started when sizes are small); and by some constant + * factor of its old size (to avoid repeated calls to this + * function taking quadratic time overall). */ + if (increment < 256 / eltsize) + increment = 256 / eltsize; + if (increment < oldsize / 16) + increment = oldsize / 16; + + /* But we also can't grow beyond maxsize. */ + size_t maxincr = maxsize - oldsize; + if (increment > maxincr) + increment = maxincr; + + size_t newsize = oldsize + increment; + void *toret = saferealloc(ptr, newsize, eltsize); + *allocated = newsize; + return toret; +} diff --git a/misc.c b/misc.c index b7a188dd..fea296b6 100644 --- a/misc.c +++ b/misc.c @@ -39,7 +39,7 @@ prompts_t *new_prompts(void) { prompts_t *p = snew(prompts_t); p->prompts = NULL; - p->n_prompts = 0; + p->n_prompts = p->prompts_size = 0; p->data = NULL; p->to_server = true; /* to be on the safe side */ p->name = p->instruction = NULL; @@ -53,9 +53,8 @@ void add_prompt(prompts_t *p, char *promptstr, bool echo) pr->echo = echo; pr->result = NULL; pr->resultsize = 0; - p->n_prompts++; - p->prompts = sresize(p->prompts, p->n_prompts, prompt_t *); - p->prompts[p->n_prompts-1] = pr; + sgrowarray(p->prompts, p->prompts_size, p->n_prompts); + p->prompts[p->n_prompts++] = pr; } void prompt_ensure_result_size(prompt_t *pr, int newlen) { diff --git a/misc.h b/misc.h index 8da4fdba..1adaf161 100644 --- a/misc.h +++ b/misc.h @@ -37,7 +37,7 @@ void burnstr(char *string); struct strbuf { char *s; unsigned char *u; - int len; + size_t len; BinarySink_IMPLEMENTATION; /* (also there's a surrounding implementation struct in misc.c) */ }; diff --git a/pscp.c b/pscp.c index c78d25f6..367cb28a 100644 --- a/pscp.c +++ b/pscp.c @@ -609,7 +609,7 @@ void scp_sftp_listdir(const char *dirname) struct fxp_name *ournames; struct sftp_packet *pktin; struct sftp_request *req; - int nnames, namesize; + size_t nnames, namesize; int i; if (!fxp_init()) { @@ -648,10 +648,7 @@ void scp_sftp_listdir(const char *dirname) break; } - if (nnames + names->nnames >= namesize) { - namesize += names->nnames + 128; - ournames = sresize(ournames, namesize, struct fxp_name); - } + sgrowarrayn(ournames, namesize, nnames, names->nnames); for (i = 0; i < names->nnames; i++) ournames[nnames++] = names->names[i]; @@ -1196,7 +1193,7 @@ int scp_get_sink_action(struct scp_sink_action *act) if (attrs.permissions & 0040000) { struct scp_sftp_dirstack *newitem; struct fxp_handle *dirhandle; - int nnames, namesize; + size_t nnames, namesize; struct fxp_name *ournames; struct fxp_names *names; @@ -1279,10 +1276,7 @@ int scp_get_sink_action(struct scp_sink_action *act) fxp_free_names(names); break; } - if (nnames + names->nnames >= namesize) { - namesize += names->nnames + 128; - ournames = sresize(ournames, namesize, struct fxp_name); - } + sgrowarrayn(ournames, namesize, nnames, names->nnames); for (i = 0; i < names->nnames; i++) { if (!strcmp(names->names[i].filename, ".") || !strcmp(names->names[i].filename, "..")) { diff --git a/psftp.c b/psftp.c index f896ac2f..7adbab70 100644 --- a/psftp.c +++ b/psftp.c @@ -264,7 +264,7 @@ bool sftp_get_file(char *fname, char *outfname, bool recurse, bool restart) (attrs.permissions & 0040000)) { struct fxp_handle *dirhandle; - int nnames, namesize; + size_t nnames, namesize; struct fxp_name **ournames; struct fxp_names *names; int i; @@ -321,10 +321,7 @@ bool sftp_get_file(char *fname, char *outfname, bool recurse, bool restart) fxp_free_names(names); break; } - if (nnames + names->nnames >= namesize) { - namesize += names->nnames + 128; - ournames = sresize(ournames, namesize, struct fxp_name *); - } + sgrowarrayn(ournames, namesize, nnames, names->nnames); for (i = 0; i < names->nnames; i++) if (strcmp(names->names[i].filename, ".") && strcmp(names->names[i].filename, "..")) { @@ -549,11 +546,11 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart) */ if (recurse && file_type(fname) == FILE_TYPE_DIRECTORY) { bool result; - int nnames, namesize; + size_t nnames, namesize; char *name, **ournames; const char *opendir_err; DirHandle *dh; - int i; + size_t i; /* * First, attempt to create the destination directory, @@ -588,10 +585,7 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart) return false; } while ((name = read_filename(dh)) != NULL) { - if (nnames >= namesize) { - namesize += 128; - ournames = sresize(ournames, namesize, char *); - } + sgrowarray(ournames, namesize, nnames); ournames[nnames++] = name; } close_directory(dh); @@ -647,7 +641,7 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart) sfree(nextoutfname); sfree(nextfname); if (!retd) { - for (i = 0; i < nnames; i++) { + for (size_t i = 0; i < nnames; i++) { sfree(ournames[i]); } sfree(ournames); @@ -658,7 +652,7 @@ bool sftp_put_file(char *fname, char *outfname, bool recurse, bool restart) /* * Done this recursion level. Free everything. */ - for (i = 0; i < nnames; i++) { + for (size_t i = 0; i < nnames; i++) { sfree(ournames[i]); } sfree(ournames); @@ -988,7 +982,7 @@ bool is_wildcard(char *name) */ struct sftp_command { char **words; - int nwords, wordssize; + size_t nwords, wordssize; int (*obey) (struct sftp_command *); /* returns <0 to quit */ }; @@ -1035,12 +1029,11 @@ int sftp_cmd_ls(struct sftp_command *cmd) struct fxp_handle *dirh; struct fxp_names *names; struct fxp_name **ournames; - int nnames, namesize; + size_t nnames, namesize; const char *dir; char *cdir, *unwcdir, *wildcard; struct sftp_packet *pktin; struct sftp_request *req; - int i; if (!backend) { not_connected(); @@ -1114,12 +1107,9 @@ int sftp_cmd_ls(struct sftp_command *cmd) break; } - if (nnames + names->nnames >= namesize) { - namesize += names->nnames + 128; - ournames = sresize(ournames, namesize, struct fxp_name *); - } + sgrowarrayn(ournames, namesize, nnames, names->nnames); - for (i = 0; i < names->nnames; i++) + for (size_t i = 0; i < names->nnames; i++) if (!wildcard || wc_match(wildcard, names->names[i].filename)) ournames[nnames++] = fxp_dup_name(&names->names[i]); @@ -1139,7 +1129,7 @@ int sftp_cmd_ls(struct sftp_command *cmd) /* * And print them. */ - for (i = 0; i < nnames; i++) { + for (size_t i = 0; i < nnames; i++) { with_stripctrl(san, ournames[i]->longname) printf("%s\n", san); fxp_free_name(ournames[i]); @@ -2257,8 +2247,8 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) * exactly two words: one containing the !, and the second * containing everything else on the line. */ - cmd->nwords = cmd->wordssize = 2; - cmd->words = sresize(cmd->words, cmd->wordssize, char *); + cmd->nwords = 2; + sgrowarrayn(cmd->words, cmd->wordssize, cmd->nwords, 0); cmd->words[0] = dupstr("!"); cmd->words[1] = dupstr(p+1); } else if (*p == '#') { @@ -2307,10 +2297,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) if (*p) p++; /* skip over the whitespace */ *r = '\0'; - if (cmd->nwords >= cmd->wordssize) { - cmd->wordssize = cmd->nwords + 16; - cmd->words = sresize(cmd->words, cmd->wordssize, char *); - } + sgrowarray(cmd->words, cmd->wordssize, cmd->nwords); cmd->words[cmd->nwords++] = dupstr(q); } } diff --git a/putty.h b/putty.h index cc14e6e7..e3767eec 100644 --- a/putty.h +++ b/putty.h @@ -665,6 +665,7 @@ typedef struct { bool instr_reqd; /* Display of `instruction' required or optional? */ size_t n_prompts; /* May be zero (in which case display the foregoing, * if any, and return success) */ + size_t prompts_size; /* allocated storage capacity for prompts[] */ prompt_t **prompts; void *data; /* slot for housekeeping data, managed by * seat_get_userpass_input(); initially NULL */ diff --git a/puttymem.h b/puttymem.h index e90d7c71..ddb04a5c 100644 --- a/puttymem.h +++ b/puttymem.h @@ -48,6 +48,47 @@ void safefree(void *); #define snew_plus(type, extra) ((type *)snmalloc(1, sizeof(type) + (extra))) #define snew_plus_get_aux(ptr) ((void *)((ptr) + 1)) +/* + * Helper macros to deal with the common use case of growing an array. + * + * The common setup is that 'array' is a pointer to the first element + * of a dynamic array of some type, and 'size' represents the current + * allocated size of that array (in elements). Both of those macro + * parameters are implicitly written back to. + * + * Then sgrowarray(array, size, n) means: make sure the nth element of + * the array exists (i.e. the size is at least n+1). You call that + * before writing to the nth element, if you're looping round + * appending to the array. + * + * If you need to grow the array by more than one element, you can + * instead call sgrowarrayn(array, size, n, m), which will ensure the + * size of the array is at least n+m. (So sgrowarray is just the + * special case of that in which m == 1.) + * + * It's common to call sgrowarrayn with one of n,m equal to the + * previous logical length of the array, and the other equal to the + * new number of logical entries you want to add, so that n <= size on + * entry. But that's not actually a mandatory precondition: the two + * length parameters are just arbitrary integers that get added + * together with an initial check for overflow, and the semantics are + * simply 'make sure the array is big enough to take their sum, no + * matter how big it was to start with'.) + * + * Another occasionally useful idiom is to call sgrowarray with n == + * size, i.e. sgrowarray(array, size, size). That just means: make + * array bigger by _some_ amount, I don't particularly mind how much. + * You might use that style if you were repeatedly calling an API + * function outside your control, which would either fill your buffer + * and return success, or else return a 'too big' error without + * telling you how much bigger it needed to be. + */ +void *safegrowarray(void *array, size_t *size, size_t eltsize, + size_t oldlen, size_t extralen); +#define sgrowarrayn(array, size, n, m) \ + ((array) = safegrowarray(array, &(size), sizeof(*array), n, m)) +#define sgrowarray(array, size, n) sgrowarrayn(array, size, n, 1) + /* * This function is called by the innermost safemalloc/saferealloc * functions when allocation fails. Usually it's provided by misc.c diff --git a/sftp.h b/sftp.h index 2b388b65..0b4ad92d 100644 --- a/sftp.h +++ b/sftp.h @@ -126,8 +126,7 @@ struct sftp_request; struct sftp_packet { char *data; - unsigned length, maxlen; - unsigned savedpos; + size_t length, maxlen, savedpos; int type; BinarySink_IMPLEMENTATION; BinarySource_IMPLEMENTATION; diff --git a/sftpcommon.c b/sftpcommon.c index aef6c247..34ba4247 100644 --- a/sftpcommon.c +++ b/sftpcommon.c @@ -15,18 +15,12 @@ static void sftp_pkt_BinarySink_write( BinarySink *bs, const void *data, size_t length) { struct sftp_packet *pkt = BinarySink_DOWNCAST(bs, struct sftp_packet); - unsigned newlen; assert(length <= 0xFFFFFFFFU - pkt->length); - newlen = pkt->length + length; - if (pkt->maxlen < newlen) { - pkt->maxlen = newlen * 5 / 4 + 256; - pkt->data = sresize(pkt->data, pkt->maxlen, char); - } - + sgrowarrayn(pkt->data, pkt->maxlen, pkt->length, length); memcpy(pkt->data + pkt->length, data, length); - pkt->length = newlen; + pkt->length += length; } struct sftp_packet *sftp_pkt_init(int type) diff --git a/ssh.c b/ssh.c index 73aa3557..dca0a728 100644 --- a/ssh.c +++ b/ssh.c @@ -981,7 +981,7 @@ static void ssh_size(Backend *be, int width, int height) struct ssh_add_special_ctx { SessionSpecial *specials; - int nspecials, specials_size; + size_t nspecials, specials_size; }; static void ssh_add_special(void *vctx, const char *text, @@ -990,12 +990,7 @@ static void ssh_add_special(void *vctx, const char *text, struct ssh_add_special_ctx *ctx = (struct ssh_add_special_ctx *)vctx; SessionSpecial *spec; - if (ctx->nspecials >= ctx->specials_size) { - ctx->specials_size = ctx->nspecials * 5 / 4 + 32; - ctx->specials = sresize(ctx->specials, ctx->specials_size, - SessionSpecial); - } - + sgrowarray(ctx->specials, ctx->specials_size, ctx->nspecials); spec = &ctx->specials[ctx->nspecials++]; spec->name = text; spec->code = code; diff --git a/ssh.h b/ssh.h index 3af4065b..e769e5f7 100644 --- a/ssh.h +++ b/ssh.h @@ -63,12 +63,12 @@ typedef struct PktIn { } PktIn; typedef struct PktOut { - long prefix; /* bytes up to and including type field */ - long length; /* total bytes, including prefix */ + size_t prefix; /* bytes up to and including type field */ + size_t length; /* total bytes, including prefix */ int type; - long minlen; /* SSH-2: ensure wire length is at least this */ + size_t minlen; /* SSH-2: ensure wire length is at least this */ unsigned char *data; /* allocated storage */ - long maxlen; /* amount of storage allocated for `data' */ + size_t maxlen; /* amount of storage allocated for `data' */ /* Extra metadata used in SSH packet logging mode, allowing us to * log in the packet header line that the packet came from a diff --git a/sshcommon.c b/sshcommon.c index 65cce855..e49eb0ee 100644 --- a/sshcommon.c +++ b/sshcommon.c @@ -230,18 +230,11 @@ PktOut *ssh_new_packet(void) return pkt; } -static void ssh_pkt_ensure(PktOut *pkt, int length) -{ - if (pkt->maxlen < length) { - pkt->maxlen = length + 256; - pkt->data = sresize(pkt->data, pkt->maxlen, unsigned char); - } -} static void ssh_pkt_adddata(PktOut *pkt, const void *data, int len) { + sgrowarrayn(pkt->data, pkt->maxlen, pkt->length, len); + memcpy(pkt->data + pkt->length, data, len); pkt->length += len; - ssh_pkt_ensure(pkt, pkt->length); - memcpy(pkt->data + pkt->length - len, data, len); } static void ssh_pkt_BinarySink_write(BinarySink *bs, diff --git a/terminal.c b/terminal.c index 929e1ec8..4f6776c8 100644 --- a/terminal.c +++ b/terminal.c @@ -4869,14 +4869,11 @@ static void term_bidi_cache_store(Terminal *term, int line, termchar *lbefore, termchar *lafter, bidi_char *wcTo, int width, int size) { - int i, j; + size_t i, j; if (!term->pre_bidi_cache || term->bidi_cache_size <= line) { - j = term->bidi_cache_size; - term->bidi_cache_size = line+1; - term->pre_bidi_cache = sresize(term->pre_bidi_cache, - term->bidi_cache_size, - struct bidi_cache_entry); + j = term->bidi_cache_size; + sgrowarray(term->pre_bidi_cache, term->bidi_cache_size, line); term->post_bidi_cache = sresize(term->post_bidi_cache, term->bidi_cache_size, struct bidi_cache_entry); @@ -5061,7 +5058,7 @@ static void do_paint(Terminal *term) int rv, cursor; pos scrpos; wchar_t *ch; - int chlen; + size_t chlen; termchar *newline; chlen = 1024; @@ -5375,10 +5372,7 @@ static void do_paint(Terminal *term) dirty_run = true; } - if (ccount+2 > chlen) { - chlen = ccount + 256; - ch = sresize(ch, chlen, wchar_t); - } + sgrowarrayn(ch, chlen, ccount, 2); #ifdef PLATFORM_IS_UTF16 if (tchar > 0x10000 && tchar < 0x110000) { @@ -5409,10 +5403,7 @@ static void do_paint(Terminal *term) break; } - if (ccount+2 > chlen) { - chlen = ccount + 256; - ch = sresize(ch, chlen, wchar_t); - } + sgrowarrayn(ch, chlen, ccount, 2); #ifdef PLATFORM_IS_UTF16 if (schar > 0x10000 && schar < 0x110000) { @@ -5552,8 +5543,8 @@ void term_scroll_to_selection(Terminal *term, int which_end) * Helper routine for clipme(): growing buffer. */ typedef struct { - int buflen; /* amount of allocated space in textbuf/attrbuf */ - int bufpos; /* amount of actual data */ + size_t bufsize; /* amount of allocated space in textbuf/attrbuf */ + size_t bufpos; /* amount of actual data */ wchar_t *textbuf; /* buffer for copied text */ wchar_t *textptr; /* = textbuf + bufpos (current insertion point) */ int *attrbuf; /* buffer for copied attributes */ @@ -5564,13 +5555,12 @@ typedef struct { static void clip_addchar(clip_workbuf *b, wchar_t chr, int attr, truecolour tc) { - if (b->bufpos >= b->buflen) { - b->buflen *= 2; - b->textbuf = sresize(b->textbuf, b->buflen, wchar_t); + if (b->bufpos >= b->bufsize) { + sgrowarray(b->textbuf, b->bufsize, b->bufpos); b->textptr = b->textbuf + b->bufpos; - b->attrbuf = sresize(b->attrbuf, b->buflen, int); + b->attrbuf = sresize(b->attrbuf, b->bufsize, int); b->attrptr = b->attrbuf + b->bufpos; - b->tcbuf = sresize(b->tcbuf, b->buflen, truecolour); + b->tcbuf = sresize(b->tcbuf, b->bufsize, truecolour); b->tcptr = b->tcbuf + b->bufpos; } *b->textptr++ = chr; @@ -5587,11 +5577,11 @@ static void clipme(Terminal *term, pos top, pos bottom, bool rect, bool desel, int attr; truecolour tc; - buf.buflen = 5120; + buf.bufsize = 5120; buf.bufpos = 0; - buf.textptr = buf.textbuf = snewn(buf.buflen, wchar_t); - buf.attrptr = buf.attrbuf = snewn(buf.buflen, int); - buf.tcptr = buf.tcbuf = snewn(buf.buflen, truecolour); + buf.textptr = buf.textbuf = snewn(buf.bufsize, wchar_t); + buf.attrptr = buf.attrbuf = snewn(buf.bufsize, int); + buf.tcptr = buf.tcbuf = snewn(buf.bufsize, truecolour); old_top_x = top.x; /* needed for rect==1 */ diff --git a/terminal.h b/terminal.h index b130f886..7981fd33 100644 --- a/terminal.h +++ b/terminal.h @@ -270,7 +270,7 @@ struct terminal_tag { bidi_char *wcFrom, *wcTo; int wcFromTo_size; struct bidi_cache_entry *pre_bidi_cache, *post_bidi_cache; - int bidi_cache_size; + size_t bidi_cache_size; /* * We copy a bunch of stuff out of the Conf structure into local diff --git a/testcrypt.c b/testcrypt.c index 0421747b..8071c013 100644 --- a/testcrypt.c +++ b/testcrypt.c @@ -380,10 +380,7 @@ size_t nfinalisers, finalisersize; static void add_finaliser(finaliser_fn_t fn, void *ctx) { - if (nfinalisers >= finalisersize) { - finalisersize = nfinalisers * 5 / 4 + 16; - finalisers = sresize(finalisers, finalisersize, struct finaliser); - } + sgrowarray(finalisers, finalisersize, nfinalisers); finalisers[nfinalisers].fn = fn; finalisers[nfinalisers].ctx = ctx; nfinalisers++; diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index 1d00a22e..b8ed07cf 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -93,7 +93,7 @@ struct dlgparam { GtkWidget *currtreeitem, **treeitems; int ntreeitems; #else - int nselparams; + size_t nselparams; struct selparam *selparams; #endif struct controlbox *ctrlbox; @@ -2918,7 +2918,7 @@ GtkWidget *create_config_box(const char *title, Conf *conf, struct Shortcuts scs; struct selparam *selparams = NULL; - int nselparams = 0, selparamsize = 0; + size_t nselparams = 0, selparamsize = 0; dp = snew(struct dlgparam); dp->after = after; @@ -3040,11 +3040,7 @@ GtkWidget *create_config_box(const char *title, Conf *conf, page_num); } - if (nselparams >= selparamsize) { - selparamsize += 16; - selparams = sresize(selparams, selparamsize, - struct selparam); - } + sgrowarray(selparams, selparamsize, nselparams); selparams[nselparams].dp = dp; selparams[nselparams].panels = GTK_NOTEBOOK(panels); selparams[nselparams].panel = panelvbox; @@ -3243,8 +3239,7 @@ static void dlgparam_destroy(GtkWidget *widget, gpointer data) ctrl_free_box(dp->ctrlbox); #if GTK_CHECK_VERSION(2,0,0) if (dp->selparams) { - int i; - for (i = 0; i < dp->nselparams; i++) + for (size_t i = 0; i < dp->nselparams; i++) if (dp->selparams[i].treepath) gtk_tree_path_free(dp->selparams[i].treepath); sfree(dp->selparams); diff --git a/unix/gtkmain.c b/unix/gtkmain.c index 20826726..9cd32c26 100644 --- a/unix/gtkmain.c +++ b/unix/gtkmain.c @@ -170,7 +170,7 @@ void launch_duplicate_session(Conf *conf) for (i = 0; pty_argv[i]; i++) put_asciz(serialised, pty_argv[i]); - sprintf(option, "---[%d,%d]", pipefd[0], serialised->len); + sprintf(option, "---[%d,%zu]", pipefd[0], serialised->len); noncloexec(pipefd[0]); fork_and_exec_self(pipefd[1], option, NULL); close(pipefd[0]); diff --git a/unix/uxnet.c b/unix/uxnet.c index 0074c4b8..b60b933a 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -1584,18 +1584,16 @@ int net_service_lookup(char *service) char *get_hostname(void) { - int len = 128; + size_t size = 0; char *hostname = NULL; do { - len *= 2; - hostname = sresize(hostname, len, char); - if ((gethostname(hostname, len) < 0) && - (errno != ENAMETOOLONG)) { + sgrowarray(hostname, size, size); + if ((gethostname(hostname, size) < 0) && (errno != ENAMETOOLONG)) { sfree(hostname); hostname = NULL; break; } - } while (strlen(hostname) >= len-1); + } while (strlen(hostname) >= size-1); return hostname; } diff --git a/unix/uxpgnt.c b/unix/uxpgnt.c index 706345d1..d7fc90d0 100644 --- a/unix/uxpgnt.c +++ b/unix/uxpgnt.c @@ -734,7 +734,8 @@ void run_agent(void) unsigned long now; int *fdlist; int fd; - int i, fdsize, fdstate; + int i, fdstate; + size_t fdsize; int termination_pid = -1; bool errors = false; Conf *conf; @@ -882,10 +883,7 @@ void run_agent(void) fd = next_fd(&fdstate, &rwx)) i++; /* Expand the fdlist buffer if necessary. */ - if (i > fdsize) { - fdsize = i + 16; - fdlist = sresize(fdlist, fdsize, int); - } + sgrowarray(fdlist, fdsize, i); /* * Add all currently open fds to the select sets, and store diff --git a/unix/uxplink.c b/unix/uxplink.c index 5aae9e49..f7fc1126 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -568,7 +568,8 @@ int main(int argc, char **argv) bool sending; int *fdlist; int fd; - int i, fdsize, fdstate; + int i, fdstate; + size_t fdsize; int exitcode; bool errors; enum TriState sanitise_stdout = AUTO, sanitise_stderr = AUTO; @@ -909,10 +910,7 @@ int main(int argc, char **argv) fd = next_fd(&fdstate, &rwx)) i++; /* Expand the fdlist buffer if necessary. */ - if (i > fdsize) { - fdsize = i + 16; - fdlist = sresize(fdlist, fdsize, int); - } + sgrowarray(fdlist, fdsize, i); /* * Add all currently open fds to the select sets, and store diff --git a/unix/uxserver.c b/unix/uxserver.c index 12a9e6a5..1771c272 100644 --- a/unix/uxserver.c +++ b/unix/uxserver.c @@ -360,11 +360,12 @@ int main(int argc, char **argv) { int *fdlist; int fd; - int i, fdsize, fdstate; + int i, fdstate; + size_t fdsize; unsigned long now; ssh_key **hostkeys = NULL; - int nhostkeys = 0, hostkeysize = 0; + size_t nhostkeys = 0, hostkeysize = 0; RSAKey *hostkey1 = NULL; AuthPolicy ap; @@ -434,10 +435,7 @@ int main(int argc, char **argv) exit(1); } - if (nhostkeys >= hostkeysize) { - hostkeysize = nhostkeys * 5 / 4 + 16; - hostkeys = sresize(hostkeys, hostkeysize, ssh_key *); - } + sgrowarray(hostkeys, hostkeysize, nhostkeys); hostkeys[nhostkeys++] = key; } else if (keytype == SSH_KEYTYPE_SSH1) { if (hostkey1) { @@ -578,10 +576,7 @@ int main(int argc, char **argv) fd = next_fd(&fdstate, &rwx)) i++; /* Expand the fdlist buffer if necessary. */ - if (i > fdsize) { - fdsize = i + 16; - fdlist = sresize(fdlist, fdsize, int); - } + sgrowarray(fdlist, fdsize, i); /* * Add all currently open fds to the select sets, and store diff --git a/unix/uxsftp.c b/unix/uxsftp.c index 81691e70..0afd2a13 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -98,7 +98,7 @@ char *psftp_lcd(char *dir) char *psftp_getcwd(void) { char *buffer, *ret; - int size = 256; + size_t size = 256; buffer = snewn(size, char); while (1) { @@ -113,8 +113,7 @@ char *psftp_getcwd(void) * Otherwise, ERANGE was returned, meaning the buffer * wasn't big enough. */ - size = size * 3 / 2; - buffer = sresize(buffer, size, char); + sgrowarray(buffer, size, size); } } @@ -447,7 +446,8 @@ char *dir_file_cat(const char *dir, const char *file) static int ssh_sftp_do_select(bool include_stdin, bool no_fds_ok) { fd_set rset, wset, xset; - int i, fdsize, *fdlist; + int i, *fdlist; + size_t fdsize; int fd, fdcount, fdstate, rwx, ret, maxfd; unsigned long now = GETTICKCOUNT(); unsigned long next; @@ -467,10 +467,7 @@ static int ssh_sftp_do_select(bool include_stdin, bool no_fds_ok) return -1; /* doom */ /* Expand the fdlist buffer if necessary. */ - if (i > fdsize) { - fdsize = i + 16; - fdlist = sresize(fdlist, fdsize, int); - } + sgrowarray(fdlist, fdsize, i); FD_ZERO(&rset); FD_ZERO(&wset); @@ -571,7 +568,8 @@ int ssh_sftp_loop_iteration(void) char *ssh_sftp_get_cmdline(const char *prompt, bool no_fds_ok) { char *buf; - int buflen, bufsize, ret; + size_t buflen, bufsize; + int ret; fputs(prompt, stdout); fflush(stdout); @@ -587,10 +585,7 @@ char *ssh_sftp_get_cmdline(const char *prompt, bool no_fds_ok) return NULL; /* woop woop */ } if (ret > 0) { - if (buflen >= bufsize) { - bufsize = buflen + 512; - buf = sresize(buf, bufsize, char); - } + sgrowarray(buf, bufsize, buflen); ret = read(0, buf+buflen, 1); if (ret < 0) { perror("read"); diff --git a/unix/uxsftpserver.c b/unix/uxsftpserver.c index 534f6965..6fab0ba0 100644 --- a/unix/uxsftpserver.c +++ b/unix/uxsftpserver.c @@ -28,7 +28,7 @@ typedef struct UnixSftpServer UnixSftpServer; struct UnixSftpServer { unsigned *fdseqs; bool *fdsopen; - int fdsize; + size_t fdsize; tree234 *dirhandles; int last_dirhandle_index; @@ -74,9 +74,8 @@ static void uss_free(SftpServer *srv) { UnixSftpServer *uss = container_of(srv, UnixSftpServer, srv); struct uss_dirhandle *udh; - int i; - for (i = 0; i < uss->fdsize; i++) + for (size_t i = 0; i < uss->fdsize; i++) if (uss->fdsopen[i]) close(i); sfree(uss->fdseqs); @@ -118,9 +117,8 @@ static void uss_return_new_handle( { assert(fd >= 0); if (fd >= uss->fdsize) { - int old_size = uss->fdsize; - uss->fdsize = fd * 5 / 4 + 32; - uss->fdseqs = sresize(uss->fdseqs, uss->fdsize, unsigned); + size_t old_size = uss->fdsize; + sgrowarray(uss->fdseqs, uss->fdsize, fd); uss->fdsopen = sresize(uss->fdsopen, uss->fdsize, bool); while (old_size < uss->fdsize) { uss->fdseqs[old_size] = 0; diff --git a/unix/x11misc.c b/unix/x11misc.c index b49aa489..813773c2 100644 --- a/unix/x11misc.c +++ b/unix/x11misc.c @@ -34,12 +34,11 @@ struct x11_err_to_ignore { struct x11_err_to_ignore *errs; -int nerrs, errsize; +size_t nerrs, errsize; static int x11_error_handler(Display *thisdisp, XErrorEvent *err) { - int i; - for (i = 0; i < nerrs; i++) { + for (size_t i = 0; i < nerrs; i++) { if (thisdisp == errs[i].display && err->serial == errs[i].serial && err->error_code == errs[i].error_code) { @@ -65,7 +64,7 @@ void x11_ignore_error(Display *disp, unsigned char errcode) */ { unsigned long last = LastKnownRequestProcessed(disp); - int i, j; + size_t i, j; for (i = j = 0; i < nerrs; i++) { if (errs[i].display == disp && errs[i].serial <= last) continue; @@ -74,10 +73,7 @@ void x11_ignore_error(Display *disp, unsigned char errcode) nerrs = j; } - if (nerrs >= errsize) { - errsize = nerrs * 5 / 4 + 16; - errs = sresize(errs, errsize, struct x11_err_to_ignore); - } + sgrowarray(errs, errsize, nerrs); errs[nerrs].display = disp; errs[nerrs].error_code = errcode; errs[nerrs].serial = NextRequest(disp); diff --git a/utils.c b/utils.c index 3f02bd66..ab0298e9 100644 --- a/utils.c +++ b/utils.c @@ -290,6 +290,18 @@ int string_length_for_printf(size_t s) return s; } +/* Work around lack of va_copy in old MSC */ +#if defined _MSC_VER && !defined va_copy +#define va_copy(a, b) TYPECHECK( \ + (va_list *)0 == &(a) && (va_list *)0 == &(b), \ + memcpy(&a, &b, sizeof(va_list))) +#endif + +/* Also lack of vsnprintf before VS2015 */ +#if defined _WINDOWS && !defined __WINE__ && _MSC_VER < 1900 +#define vsnprintf _vsnprintf +#endif + /* * Do an sprintf(), but into a custom-allocated buffer. * @@ -325,65 +337,40 @@ int string_length_for_printf(size_t s) * directive we don't know about, we should panic and die rather * than run any risk. */ -static char *dupvprintf_inner(char *buf, int oldlen, int *oldsize, +static char *dupvprintf_inner(char *buf, size_t oldlen, size_t *sizeptr, const char *fmt, va_list ap) { - int len, size, newsize; + size_t len, size; - assert(*oldsize >= oldlen); - size = *oldsize - oldlen; - if (size == 0) { - size = 512; - newsize = oldlen + size; - buf = sresize(buf, newsize, char); - } else { - newsize = *oldsize; - } + size = *sizeptr; + sgrowarrayn(buf, size, oldlen, 512); while (1) { -#if defined _WINDOWS && !defined __WINE__ && _MSC_VER < 1900 /* 1900 == VS2015 has real snprintf */ -#define vsnprintf _vsnprintf -#endif -#ifdef va_copy - /* Use the `va_copy' macro mandated by C99, if present. - * XXX some environments may have this as __va_copy() */ va_list aq; va_copy(aq, ap); - len = vsnprintf(buf + oldlen, size, fmt, aq); + len = vsnprintf(buf + oldlen, size - oldlen, fmt, aq); va_end(aq); -#else - /* Ugh. No va_copy macro, so do something nasty. - * Technically, you can't reuse a va_list like this: it is left - * unspecified whether advancing a va_list pointer modifies its - * value or something it points to, so on some platforms calling - * vsnprintf twice on the same va_list might fail hideously - * (indeed, it has been observed to). - * XXX the autoconf manual suggests that using memcpy() will give - * "maximum portability". */ - len = vsnprintf(buf + oldlen, size, fmt, ap); -#endif + if (len >= 0 && len < size) { /* This is the C99-specified criterion for snprintf to have * been completely successful. */ - *oldsize = newsize; + *sizeptr = size; return buf; } else if (len > 0) { /* This is the C99 error condition: the returned length is * the required buffer size not counting the NUL. */ - size = len + 1; + sgrowarrayn(buf, size, oldlen, len + 1); } else { /* This is the pre-C99 glibc error condition: <0 means the * buffer wasn't big enough, so we enlarge it a bit and hope. */ - size += 512; + sgrowarray(buf, size, size); } - newsize = oldlen + size; - buf = sresize(buf, newsize, char); } } char *dupvprintf(const char *fmt, va_list ap) { - int size = 0; + size_t size = 0; return dupvprintf_inner(NULL, 0, &size, fmt, ap); } char *dupprintf(const char *fmt, ...) @@ -397,22 +384,21 @@ char *dupprintf(const char *fmt, ...) } struct strbuf_impl { - int size; + size_t size; struct strbuf visible; }; +#define STRBUF_SET_UPTR(buf) \ + ((buf)->visible.u = (unsigned char *)(buf)->visible.s) #define STRBUF_SET_PTR(buf, ptr) \ - ((buf)->visible.s = (ptr), \ - (buf)->visible.u = (unsigned char *)(buf)->visible.s) + ((buf)->visible.s = (ptr), STRBUF_SET_UPTR(buf)) void *strbuf_append(strbuf *buf_o, size_t len) { struct strbuf_impl *buf = container_of(buf_o, struct strbuf_impl, visible); char *toret; - if (buf->size < buf->visible.len + len + 1) { - buf->size = (buf->visible.len + len + 1) * 5 / 4 + 512; - STRBUF_SET_PTR(buf, sresize(buf->visible.s, buf->size, char)); - } + sgrowarrayn(buf->visible.s, buf->size, buf->visible.len + 1, len); + STRBUF_SET_UPTR(buf); toret = buf->visible.s + buf->visible.len; buf->visible.len += len; buf->visible.s[buf->visible.len] = '\0'; @@ -487,13 +473,12 @@ void strbuf_finalise_agent_query(strbuf *buf_o) char *fgetline(FILE *fp) { char *ret = snewn(512, char); - int size = 512, len = 0; + size_t size = 512, len = 0; while (fgets(ret + len, size - len, fp)) { len += strlen(ret + len); if (len > 0 && ret[len-1] == '\n') break; /* got a newline, we're done */ - size = len + 512; - ret = sresize(ret, size, char); + sgrowarrayn(ret, size, len, 512); } if (len == 0) { /* first fgets returned NULL */ sfree(ret); diff --git a/windows/window.c b/windows/window.c index 781e8b88..6c1e1931 100644 --- a/windows/window.c +++ b/windows/window.c @@ -3488,7 +3488,7 @@ static void do_text_internal( bool opaque; bool is_cursor = false; static int *lpDx = NULL; - static int lpDx_len = 0; + static size_t lpDx_len = 0; int *lpDx_maybe; int len2; /* for SURROGATE PAIR */ @@ -3699,9 +3699,7 @@ static void do_text_internal( } if (len > lpDx_len) { - lpDx_len = len * 9 / 8 + 16; - lpDx = sresize(lpDx, lpDx_len, int); - + sgrowarray(lpDx, lpDx_len, len); if (lpDx_maybe) lpDx_maybe = lpDx; } @@ -3780,14 +3778,10 @@ static void do_text_internal( lpDx[0] = -1; } else if (DIRECT_FONT(text[0])) { static char *directbuf = NULL; - static int directlen = 0; - int i; - if (len > directlen) { - directlen = len; - directbuf = sresize(directbuf, directlen, char); - } + static size_t directlen = 0; - for (i = 0; i < len; i++) + sgrowarray(directbuf, directlen, len); + for (size_t i = 0; i < len; i++) directbuf[i] = text[i] & 0xFF; ExtTextOut(wintw_hdc, x + xoffset, diff --git a/windows/winhandl.c b/windows/winhandl.c index 739e2666..6e2c4be0 100644 --- a/windows/winhandl.c +++ b/windows/winhandl.c @@ -541,7 +541,8 @@ HANDLE *handle_get_events(int *nevents) { HANDLE *ret; struct handle *h; - int i, n, size; + int i; + size_t n, size; /* * Go through our tree counting the handle objects currently @@ -552,10 +553,7 @@ HANDLE *handle_get_events(int *nevents) if (handles_by_evtomain) { for (i = 0; (h = index234(handles_by_evtomain, i)) != NULL; i++) { if (h->u.g.busy) { - if (n >= size) { - size += 32; - ret = sresize(ret, size, HANDLE); - } + sgrowarray(ret, size, n); ret[n++] = h->u.g.ev_to_main; } } diff --git a/windows/winmisc.c b/windows/winmisc.c index abba8085..2df3a6b0 100644 --- a/windows/winmisc.c +++ b/windows/winmisc.c @@ -223,16 +223,14 @@ HMODULE load_system32_dll(const char *libname) * path.) */ static char *sysdir = NULL; + static size_t sysdirsize = 0; char *fullpath; HMODULE ret; if (!sysdir) { - int size = 0, len; - do { - size = 3*size/2 + 512; - sysdir = sresize(sysdir, size, char); - len = GetSystemDirectory(sysdir, size); - } while (len >= size); + size_t len; + while ((len = GetSystemDirectory(sysdir, sysdirsize)) >= sysdirsize) + sgrowarray(sysdir, sysdirsize, len); } fullpath = dupcat(sysdir, "\\", libname, NULL); diff --git a/windows/winplink.c b/windows/winplink.c index 0bcb6564..37fb4890 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -262,7 +262,7 @@ int main(int argc, char **argv) { bool sending; SOCKET *sklist; - int skcount, sksize; + size_t skcount, sksize; int exitcode; bool errors; bool use_subsystem = false; @@ -579,10 +579,7 @@ int main(int argc, char **argv) socket = next_socket(&socketstate)) i++; /* Expand the buffer if necessary. */ - if (i > sksize) { - sksize = i + 16; - sklist = sresize(sklist, sksize, SOCKET); - } + sgrowarray(sklist, sksize, i); /* Retrieve the sockets into sklist. */ skcount = 0; diff --git a/windows/winsftp.c b/windows/winsftp.c index 31683e5a..45d38d57 100644 --- a/windows/winsftp.c +++ b/windows/winsftp.c @@ -63,7 +63,7 @@ char *psftp_lcd(char *dir) char *psftp_getcwd(void) { char *ret = snewn(256, char); - int len = GetCurrentDirectory(256, ret); + size_t len = GetCurrentDirectory(256, ret); if (len > 256) ret = sresize(ret, len, char); GetCurrentDirectory(len, ret); diff --git a/windows/winstore.c b/windows/winstore.c index 5f003354..c846bd66 100644 --- a/windows/winstore.c +++ b/windows/winstore.c @@ -298,8 +298,7 @@ bool enum_settings_next(settings_e *e, strbuf *sb) success = (retd == ERROR_SUCCESS); break; } - regbuf_size = regbuf_size * 5 / 4 + 256; - regbuf = sresize(regbuf, regbuf_size, char); + sgrowarray(regbuf, regbuf_size, regbuf_size); } if (success) diff --git a/windows/winutils.c b/windows/winutils.c index 5edde65b..a5fedb8e 100644 --- a/windows/winutils.c +++ b/windows/winutils.c @@ -160,11 +160,10 @@ void pgp_fingerprints(void) char *GetDlgItemText_alloc(HWND hwnd, int id) { char *ret = NULL; - int size = 0; + size_t size = 0; do { - size = size * 4 / 3 + 512; - ret = sresize(ret, size, char); + sgrowarray(ret, size, size); GetDlgItemText(hwnd, id, ret, size); } while (!memchr(ret, '\0', size-1));