X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=misc.c;h=6cc817103b5a105d625bd76f6846b6a8326a47d1;hb=fb839a27fb8cab36b42c7e19bfd5281f98641676;hp=a53aa1274236753505f698b947cbceda819eb328;hpb=6179c5cc7cf993d0e1b69d3982584d82911e6d08;p=PuTTY.git diff --git a/misc.c b/misc.c index a53aa127..6cc81710 100644 --- a/misc.c +++ b/misc.c @@ -175,7 +175,7 @@ int main(void) return fails != 0 ? 1 : 0; } /* Stubs to stop the rest of this module causing compile failures. */ -void modalfatalbox(char *fmt, ...) {} +void modalfatalbox(const char *fmt, ...) {} int conf_get_int(Conf *conf, int primary) { return 0; } char *conf_get_str(Conf *conf, int primary) { return NULL; } #endif /* TEST_HOST_STRFOO */ @@ -394,25 +394,19 @@ int toint(unsigned u) * directive we don't know about, we should panic and die rather * than run any risk. */ -char *dupprintf(const char *fmt, ...) -{ - char *ret; - va_list ap; - va_start(ap, fmt); - ret = dupvprintf(fmt, ap); - va_end(ap); - return ret; -} -char *dupvprintf(const char *fmt, va_list ap) +static char *dupvprintf_inner(char *buf, int oldlen, int oldsize, + const char *fmt, va_list ap) { - char *buf; int len, size; - buf = snewn(512, char); - size = 512; + size = oldsize - oldlen; + if (size == 0) { + size = 512; + buf = sresize(buf, oldlen + size, char); + } while (1) { -#ifdef _WINDOWS +#if defined _WINDOWS && !defined __WINE__ && _MSC_VER < 1900 /* 1900 == VS2015 has real snprintf */ #define vsnprintf _vsnprintf #endif #ifdef va_copy @@ -420,7 +414,7 @@ char *dupvprintf(const char *fmt, va_list ap) * XXX some environments may have this as __va_copy() */ va_list aq; va_copy(aq, ap); - len = vsnprintf(buf, size, fmt, aq); + len = vsnprintf(buf + oldlen, size, fmt, aq); va_end(aq); #else /* Ugh. No va_copy macro, so do something nasty. @@ -431,7 +425,7 @@ char *dupvprintf(const char *fmt, va_list ap) * (indeed, it has been observed to). * XXX the autoconf manual suggests that using memcpy() will give * "maximum portability". */ - len = vsnprintf(buf, size, fmt, ap); + len = vsnprintf(buf + oldlen, size, fmt, ap); #endif if (len >= 0 && len < size) { /* This is the C99-specified criterion for snprintf to have @@ -446,10 +440,65 @@ char *dupvprintf(const char *fmt, va_list ap) * buffer wasn't big enough, so we enlarge it a bit and hope. */ size += 512; } - buf = sresize(buf, size, char); + buf = sresize(buf, oldlen + size, char); } } +char *dupvprintf(const char *fmt, va_list ap) +{ + return dupvprintf_inner(NULL, 0, 0, fmt, ap); +} +char *dupprintf(const char *fmt, ...) +{ + char *ret; + va_list ap; + va_start(ap, fmt); + ret = dupvprintf(fmt, ap); + va_end(ap); + return ret; +} + +struct strbuf { + char *s; + int len, size; +}; +strbuf *strbuf_new(void) +{ + strbuf *buf = snew(strbuf); + buf->len = 0; + buf->size = 512; + buf->s = snewn(buf->size, char); + *buf->s = '\0'; + return buf; +} +void strbuf_free(strbuf *buf) +{ + sfree(buf->s); + sfree(buf); +} +char *strbuf_str(strbuf *buf) +{ + return buf->s; +} +char *strbuf_to_str(strbuf *buf) +{ + char *ret = buf->s; + sfree(buf); + return ret; +} +void strbuf_catfv(strbuf *buf, const char *fmt, va_list ap) +{ + buf->s = dupvprintf_inner(buf->s, buf->len, buf->size, fmt, ap); + buf->len += strlen(buf->s + buf->len); +} +void strbuf_catf(strbuf *buf, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + strbuf_catfv(buf, fmt, ap); + va_end(ap); +} + /* * Read an entire line of text from a file. Return a buffer * malloced to be as big as necessary (caller must free). @@ -460,7 +509,7 @@ char *fgetline(FILE *fp) int size = 512, len = 0; while (fgets(ret + len, size - len, fp)) { len += strlen(ret + len); - if (ret[len-1] == '\n') + if (len > 0 && ret[len-1] == '\n') break; /* got a newline, we're done */ size = len + 512; ret = sresize(ret, size, char); @@ -495,7 +544,7 @@ char *chomp(char *str) * Core base64 encoding and decoding routines. */ -void base64_encode_atom(unsigned char *data, int n, char *out) +void base64_encode_atom(const unsigned char *data, int n, char *out) { static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -519,7 +568,7 @@ void base64_encode_atom(unsigned char *data, int n, char *out) out[3] = '='; } -int base64_decode_atom(char *atom, unsigned char *out) +int base64_decode_atom(const char *atom, unsigned char *out) { int vals[4]; int i, v, len; @@ -755,7 +804,7 @@ void *safemalloc(size_t n, size_t size) #else strcpy(str, "Out of memory!"); #endif - modalfatalbox(str); + modalfatalbox("%s", str); } #ifdef MALLOC_LOG if (fp) @@ -797,7 +846,7 @@ void *saferealloc(void *ptr, size_t n, size_t size) #else strcpy(str, "Out of memory!"); #endif - modalfatalbox(str); + modalfatalbox("%s", str); } #ifdef MALLOC_LOG if (fp) @@ -830,7 +879,7 @@ void safefree(void *ptr) */ #ifdef DEBUG -extern void dputs(char *); /* defined in per-platform *misc.c */ +extern void dputs(const char *); /* defined in per-platform *misc.c */ void debug_printf(const char *fmt, ...) { @@ -853,7 +902,7 @@ void debug_memdump(const void *buf, int len, int L) if (L) { int delta; debug_printf("\t%d (0x%x) bytes:\n", len, len); - delta = 15 & (unsigned long int) p; + delta = 15 & (uintptr_t)p; p -= delta; len += delta; } @@ -1064,12 +1113,12 @@ int match_ssh_id(int stringlen, const void *string, const char *id) void *get_ssh_string(int *datalen, const void **data, int *stringlen) { void *ret; - int len; + unsigned int len; if (*datalen < 4) return NULL; len = GET_32BIT_MSB_FIRST((const unsigned char *)*data); - if (*datalen < len+4) + if (*datalen - 4 < len) return NULL; ret = (void *)((const char *)*data + 4); *datalen -= len + 4; @@ -1087,3 +1136,90 @@ int get_ssh_uint32(int *datalen, const void **data, unsigned *ret) *data = (const char *)*data + 4; return TRUE; } + +int strstartswith(const char *s, const char *t) +{ + return !memcmp(s, t, strlen(t)); +} + +int strendswith(const char *s, const char *t) +{ + size_t slen = strlen(s), tlen = strlen(t); + return slen >= tlen && !strcmp(s + (slen - tlen), t); +} + +char *buildinfo(const char *newline) +{ + strbuf *buf = strbuf_new(); + extern const char commitid[]; /* in commitid.c */ + + strbuf_catf(buf, "Build platform: %d-bit %s", + (int)(CHAR_BIT * sizeof(void *)), + BUILDINFO_PLATFORM); + +#ifdef __clang_version__ + strbuf_catf(buf, "%sCompiler: clang %s", newline, __clang_version__); +#elif defined __GNUC__ && defined __VERSION__ + strbuf_catf(buf, "%sCompiler: gcc %s", newline, __VERSION__); +#elif defined _MSC_VER + strbuf_catf(buf, "%sCompiler: Visual Studio", newline); +#if _MSC_VER == 1900 + strbuf_catf(buf, " 2015 / MSVC++ 14.0"); +#elif _MSC_VER == 1800 + strbuf_catf(buf, " 2013 / MSVC++ 12.0"); +#elif _MSC_VER == 1700 + strbuf_catf(buf, " 2012 / MSVC++ 11.0"); +#elif _MSC_VER == 1600 + strbuf_catf(buf, " 2010 / MSVC++ 10.0"); +#elif _MSC_VER == 1500 + strbuf_catf(buf, " 2008 / MSVC++ 9.0"); +#elif _MSC_VER == 1400 + strbuf_catf(buf, " 2005 / MSVC++ 8.0"); +#elif _MSC_VER == 1310 + strbuf_catf(buf, " 2003 / MSVC++ 7.1"); +#else + strbuf_catf(buf, ", unrecognised version"); +#endif + strbuf_catf(buf, " (_MSC_VER=%d)", (int)_MSC_VER); +#endif + +#ifdef BUILDINFO_GTK + { + char *gtk_buildinfo = buildinfo_gtk_version(); + if (gtk_buildinfo) { + strbuf_catf(buf, "%sCompiled against GTK version %s", + newline, gtk_buildinfo); + sfree(gtk_buildinfo); + } + } +#endif + +#ifdef NO_SECURITY + strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline); +#endif +#ifdef NO_SECUREZEROMEMORY + strbuf_catf(buf, "%sBuild option: NO_SECUREZEROMEMORY", newline); +#endif +#ifdef NO_IPV6 + strbuf_catf(buf, "%sBuild option: NO_IPV6", newline); +#endif +#ifdef NO_GSSAPI + strbuf_catf(buf, "%sBuild option: NO_GSSAPI", newline); +#endif +#ifdef STATIC_GSSAPI + strbuf_catf(buf, "%sBuild option: STATIC_GSSAPI", newline); +#endif +#ifdef UNPROTECT + strbuf_catf(buf, "%sBuild option: UNPROTECT", newline); +#endif +#ifdef FUZZING + strbuf_catf(buf, "%sBuild option: FUZZING", newline); +#endif +#ifdef DEBUG + strbuf_catf(buf, "%sBuild option: DEBUG", newline); +#endif + + strbuf_catf(buf, "%sSource commit: %s", newline, commitid); + + return strbuf_to_str(buf); +}