浏览代码

PuTTY snapshot 0112936e (Replace assert(false) with an unreachable() macro - 2019-01-03)

Source commit: 5f557bde974a30d0e724b54f03d5d1f66a64de7b
Martin Prikryl 6 年之前
父节点
当前提交
08989cdbc2

+ 21 - 12
source/putty/doc/udp.but

@@ -42,18 +42,27 @@ to do endianness-dependent operations, and so on.
 some of these portability issues. The Windows front end compiles on
 some of these portability issues. The Windows front end compiles on
 both 32- and 64-bit x86 and also Arm.)
 both 32- and 64-bit x86 and also Arm.)
 
 
-Our current choice of C standards version is C99: you can assume that
-C99 features are available (in particular \cw{<stdint.h>},
-\cw{<stdbool.h>} and \c{inline}), but you shouldn't use things that
-are new in C11 (such as \cw{<uchar.h>} or \cw{_Generic}).
-
-One small exception to that: for historical reasons, we still build in
-one configuration which lacks \cw{<inttypes.h>}. So that file is
-included centrally in \c{defs.h}, and has a set of workaround
-definitions for the \cw{PRIx64}-type macros we use. If you need to use
-another one of those macros, you need to add a workaround definition
-in \c{defs.h}, and don't casually re-include \cw{<inttypes.h>}
-anywhere else in the source file.
+Our current choice of C standards version is \e{mostly} C99. With a
+couple of exceptions, you can assume that C99 features are available
+(in particular \cw{<stdint.h>}, \cw{<stdbool.h>} and \c{inline}), but
+you shouldn't use things that are new in C11 (such as \cw{<uchar.h>}
+or \cw{_Generic}).
+
+The exceptions to that rule are due to the need for Visual Studio
+compatibility:
+
+\b Don't use variable-length arrays. Visual Studio doesn't support
+them even now that it's adopted the rest of C99. We use \cw{-Wvla}
+when building with gcc and clang, to make it easier to avoid
+accidentally breaking that rule.
+
+\b For historical reasons, we still build with one older VS version
+which lacks \cw{<inttypes.h>}. So that file is included centrally in
+\c{defs.h}, and has a set of workaround definitions for the
+\cw{PRIx64}-type macros we use. If you need to use another one of
+those macros, you need to add a workaround definition in \c{defs.h},
+and don't casually re-include \cw{<inttypes.h>} anywhere else in the
+source file.
 
 
 Here are a few portability assumptions that we \e{do} currently allow
 Here are a few portability assumptions that we \e{do} currently allow
 (because we'd already have to thoroughly vet the existing code if they
 (because we'd already have to thoroughly vet the existing code if they

+ 5 - 6
source/putty/import.c

@@ -750,7 +750,7 @@ static struct ssh2_userkey *openssh_pem_read(
         }
         }
 
 
     } else {
     } else {
-        assert(0 && "Bad key type from load_openssh_pem_key");
+        unreachable("Bad key type from load_openssh_pem_key");
 	errmsg = "Bad key type from load_openssh_pem_key";
 	errmsg = "Bad key type from load_openssh_pem_key";
 	goto error;
 	goto error;
     }
     }
@@ -973,8 +973,7 @@ static bool openssh_pem_write(
         header = "-----BEGIN EC PRIVATE KEY-----\n";
         header = "-----BEGIN EC PRIVATE KEY-----\n";
         footer = "-----END EC PRIVATE KEY-----\n";
         footer = "-----END EC PRIVATE KEY-----\n";
     } else {
     } else {
-        assert(0);                     /* zoinks! */
-	exit(1); /* XXX: GCC doesn't understand assert() on some systems. */
+        unreachable("bad key alg in openssh_pem_write");
     }
     }
 
 
     /*
     /*
@@ -1363,7 +1362,7 @@ static struct ssh2_userkey *openssh_new_read(
             keysize = 48;              /* 32 byte key + 16 byte IV */
             keysize = 48;              /* 32 byte key + 16 byte IV */
             break;
             break;
           default:
           default:
-            assert(0 && "Bad cipher enumeration value");
+            unreachable("Bad cipher enumeration value");
         }
         }
         assert(keysize <= sizeof(keybuf));
         assert(keysize <= sizeof(keybuf));
         switch (key->kdf) {
         switch (key->kdf) {
@@ -1378,7 +1377,7 @@ static struct ssh2_userkey *openssh_new_read(
                            keybuf, keysize);
                            keybuf, keysize);
             break;
             break;
           default:
           default:
-            assert(0 && "Bad kdf enumeration value");
+            unreachable("Bad kdf enumeration value");
         }
         }
         switch (key->cipher) {
         switch (key->cipher) {
           case ON_E_NONE:
           case ON_E_NONE:
@@ -1408,7 +1407,7 @@ static struct ssh2_userkey *openssh_new_read(
             }
             }
             break;
             break;
           default:
           default:
-            assert(0 && "Bad cipher enumeration value");
+            unreachable("Bad cipher enumeration value");
         }
         }
     }
     }
 
 

+ 18 - 0
source/putty/misc.h

@@ -11,8 +11,10 @@
 
 
 #include <stdio.h>		       /* for FILE * */
 #include <stdio.h>		       /* for FILE * */
 #include <stdarg.h>		       /* for va_list */
 #include <stdarg.h>		       /* for va_list */
+#include <stdlib.h>                    /* for abort */
 #include <time.h>                      /* for struct tm */
 #include <time.h>                      /* for struct tm */
 #include <limits.h>                    /* for INT_MAX/MIN */
 #include <limits.h>                    /* for INT_MAX/MIN */
+#include <assert.h>                    /* for assert (obviously) */
 
 
 unsigned long parse_blocksize(const char *bs);
 unsigned long parse_blocksize(const char *bs);
 char ctrlparse(char *s, char **next);
 char ctrlparse(char *s, char **next);
@@ -169,6 +171,22 @@ bool smemeq(const void *av, const void *bv, size_t len);
 
 
 char *buildinfo(const char *newline);
 char *buildinfo(const char *newline);
 
 
+/*
+ * A function you can put at points in the code where execution should
+ * never reach in the first place. Better than assert(false), or even
+ * assert(false && "some explanatory message"), because some compilers
+ * don't interpret assert(false) as a declaration of unreachability,
+ * so they may still warn about pointless things like some variable
+ * not being initialised on the unreachable code path.
+ *
+ * I follow the assertion with a call to abort() just in case someone
+ * compiles with -DNDEBUG, and I wrap that abort inside my own
+ * function labelled NORETURN just in case some unusual kind of system
+ * header wasn't foresighted enough to label abort() itself that way.
+ */
+static inline NORETURN void unreachable_internal(void) { abort(); }
+#define unreachable(msg) (assert(false && msg), unreachable_internal())
+
 /*
 /*
  * Debugging functions.
  * Debugging functions.
  *
  *

+ 1 - 1
source/putty/portfwd.c

@@ -243,7 +243,7 @@ static void pfd_receive(Plug *plug, int urgent, char *data, int len)
             switch (pf->socks_state) {
             switch (pf->socks_state) {
               case SOCKS_INITIAL:
               case SOCKS_INITIAL:
               case SOCKS_NONE:
               case SOCKS_NONE:
-                assert(0 && "These case values cannot appear");
+                unreachable("These case values cannot appear");
 
 
               case SOCKS_4:
               case SOCKS_4:
                 /* SOCKS 4/4A connect message */
                 /* SOCKS 4/4A connect message */

+ 3 - 3
source/putty/ssh.h

@@ -726,7 +726,7 @@ struct ssh2_macalg {
 
 
 #define ssh2_mac_new(alg, cipher) ((alg)->new(alg, cipher))
 #define ssh2_mac_new(alg, cipher) ((alg)->new(alg, cipher))
 #define ssh2_mac_free(ctx) ((ctx)->vt->free(ctx))
 #define ssh2_mac_free(ctx) ((ctx)->vt->free(ctx))
-#define ssh2_mac_setkey(ctx, key) ((ctx)->vt->free(ctx, key))
+#define ssh2_mac_setkey(ctx, key) ((ctx)->vt->setkey(ctx, key))
 #define ssh2_mac_start(ctx) ((ctx)->vt->start(ctx))
 #define ssh2_mac_start(ctx) ((ctx)->vt->start(ctx))
 #define ssh2_mac_genresult(ctx, out) ((ctx)->vt->genresult(ctx, out))
 #define ssh2_mac_genresult(ctx, out) ((ctx)->vt->genresult(ctx, out))
 #define ssh2_mac_alg(ctx) ((ctx)->vt)
 #define ssh2_mac_alg(ctx) ((ctx)->vt)
@@ -859,8 +859,8 @@ struct ssh2_userkey {
     char *comment;		       /* the key comment */
     char *comment;		       /* the key comment */
 };
 };
 
 
-/* The maximum length of any hash algorithm used in kex. (bytes) */
-#define SSH2_KEX_MAX_HASH_LEN (64) /* SHA-512 */
+/* The maximum length of any hash algorithm. (bytes) */
+#define MAX_HASH_LEN (64)              /* longest is SHA-512 */
 
 
 extern const struct ssh1_cipheralg ssh1_3des;
 extern const struct ssh1_cipheralg ssh1_3des;
 extern const struct ssh1_cipheralg ssh1_des;
 extern const struct ssh1_cipheralg ssh1_des;

+ 2 - 4
source/putty/ssh1connection-client.c

@@ -519,12 +519,10 @@ struct ssh_rportfwd *ssh1_rportfwd_alloc(
 SshChannel *ssh1_serverside_x11_open(
 SshChannel *ssh1_serverside_x11_open(
     ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
     ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
 {
 {
-    assert(false && "Should never be called in the client");
-    return NULL;
+    unreachable("Should never be called in the client");
 }
 }
 
 
 SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
 SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
 {
 {
-    assert(false && "Should never be called in the client");
-    return NULL;
+    unreachable("Should never be called in the client");
 }
 }

+ 2 - 2
source/putty/ssh1login.c

@@ -252,6 +252,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                 return;
                 return;
             }
             }
         } else {
         } else {
+            sfree(fingerprint);
             sfree(keystr);
             sfree(keystr);
         }
         }
     }
     }
@@ -689,8 +690,7 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
                     got_passphrase = false;
                     got_passphrase = false;
                     /* and try again */
                     /* and try again */
                 } else {
                 } else {
-                    assert(0 && "unexpected return from rsa_ssh1_loadkey()");
-                    got_passphrase = false;   /* placate optimisers */
+                    unreachable("unexpected return from rsa_ssh1_loadkey()");
                 }
                 }
             }
             }
 
 

+ 2 - 2
source/putty/ssh2bpp.c

@@ -122,7 +122,7 @@ void ssh2_bpp_new_outgoing_crypto(
     s->out.etm_mode = etm_mode;
     s->out.etm_mode = etm_mode;
     if (mac) {
     if (mac) {
         s->out.mac = ssh2_mac_new(mac, s->out.cipher);
         s->out.mac = ssh2_mac_new(mac, s->out.cipher);
-        mac->setkey(s->out.mac, mac_key);
+        ssh2_mac_setkey(s->out.mac, mac_key);
 
 
         bpp_logevent("Initialised %s outbound MAC algorithm%s%s",
         bpp_logevent("Initialised %s outbound MAC algorithm%s%s",
                      ssh2_mac_alg(s->out.mac)->text_name,
                      ssh2_mac_alg(s->out.mac)->text_name,
@@ -184,7 +184,7 @@ void ssh2_bpp_new_incoming_crypto(
     s->in.etm_mode = etm_mode;
     s->in.etm_mode = etm_mode;
     if (mac) {
     if (mac) {
         s->in.mac = ssh2_mac_new(mac, s->in.cipher);
         s->in.mac = ssh2_mac_new(mac, s->in.cipher);
-        mac->setkey(s->in.mac, mac_key);
+        ssh2_mac_setkey(s->in.mac, mac_key);
 
 
         bpp_logevent("Initialised %s inbound MAC algorithm%s%s",
         bpp_logevent("Initialised %s inbound MAC algorithm%s%s",
                      ssh2_mac_alg(s->in.mac)->text_name,
                      ssh2_mac_alg(s->in.mac)->text_name,

+ 5 - 7
source/putty/ssh2connection-client.c

@@ -304,14 +304,12 @@ SshChannel *ssh2_session_open(ConnectionLayer *cl, Channel *chan)
 SshChannel *ssh2_serverside_x11_open(
 SshChannel *ssh2_serverside_x11_open(
     ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
     ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
 {
 {
-    assert(false && "Should never be called in the client");
-    return 0;                          /* placate optimiser */
+    unreachable("Should never be called in the client");
 }
 }
 
 
 SshChannel *ssh2_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
 SshChannel *ssh2_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
 {
 {
-    assert(false && "Should never be called in the client");
-    return 0;                          /* placate optimiser */
+    unreachable("Should never be called in the client");
 }
 }
 
 
 static void ssh2_channel_response(
 static void ssh2_channel_response(
@@ -358,19 +356,19 @@ bool ssh2channel_start_subsystem(
 
 
 void ssh2channel_send_exit_status(SshChannel *sc, int status)
 void ssh2channel_send_exit_status(SshChannel *sc, int status)
 {
 {
-    assert(false && "Should never be called in the client");
+    unreachable("Should never be called in the client");
 }
 }
 
 
 void ssh2channel_send_exit_signal(
 void ssh2channel_send_exit_signal(
     SshChannel *sc, ptrlen signame, bool core_dumped, ptrlen msg)
     SshChannel *sc, ptrlen signame, bool core_dumped, ptrlen msg)
 {
 {
-    assert(false && "Should never be called in the client");
+    unreachable("Should never be called in the client");
 }
 }
 
 
 void ssh2channel_send_exit_signal_numeric(
 void ssh2channel_send_exit_signal_numeric(
     SshChannel *sc, int signum, bool core_dumped, ptrlen msg)
     SshChannel *sc, int signum, bool core_dumped, ptrlen msg)
 {
 {
-    assert(false && "Should never be called in the client");
+    unreachable("Should never be called in the client");
 }
 }
 
 
 void ssh2channel_request_x11_forwarding(
 void ssh2channel_request_x11_forwarding(

+ 1 - 1
source/putty/ssh2transport.c

@@ -927,7 +927,7 @@ static bool ssh2_scan_kexinits(
             break;
             break;
 
 
           default:
           default:
-            assert(false && "Bad list index in scan_kexinits");
+            unreachable("Bad list index in scan_kexinits");
         }
         }
     }
     }
 
 

+ 2 - 2
source/putty/ssh2transport.h

@@ -130,7 +130,7 @@ struct ssh2_transport_state {
     const struct ssh_kex *kex_alg;
     const struct ssh_kex *kex_alg;
     const ssh_keyalg *hostkey_alg;
     const ssh_keyalg *hostkey_alg;
     char *hostkey_str; /* string representation, for easy checking in rekeys */
     char *hostkey_str; /* string representation, for easy checking in rekeys */
-    unsigned char session_id[SSH2_KEX_MAX_HASH_LEN];
+    unsigned char session_id[MAX_HASH_LEN];
     int session_id_len;
     int session_id_len;
     int dh_min_size, dh_max_size;
     int dh_min_size, dh_max_size;
     bool dh_got_size_bounds;
     bool dh_got_size_bounds;
@@ -177,7 +177,7 @@ struct ssh2_transport_state {
     ssh_key *hkey;                     /* actual host key */
     ssh_key *hkey;                     /* actual host key */
     struct RSAKey *rsa_kex_key;             /* for RSA kex */
     struct RSAKey *rsa_kex_key;             /* for RSA kex */
     ecdh_key *ecdh_key;                     /* for ECDH kex */
     ecdh_key *ecdh_key;                     /* for ECDH kex */
-    unsigned char exchange_hash[SSH2_KEX_MAX_HASH_LEN];
+    unsigned char exchange_hash[MAX_HASH_LEN];
     bool can_gssapi_keyex;
     bool can_gssapi_keyex;
     bool need_gss_transient_hostkey;
     bool need_gss_transient_hostkey;
     bool warned_about_no_gss_transient_hostkey;
     bool warned_about_no_gss_transient_hostkey;

+ 9 - 9
source/putty/sshaes.c

@@ -860,7 +860,7 @@ static void aes_encrypt_cbc_sw(unsigned char *blk, int len, AESContext * ctx)
             ENCLASTROUND;
             ENCLASTROUND;
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 	for (i = 0; i < 4; i++)
 	for (i = 0; i < 4; i++)
             PUT_32BIT_MSB_FIRST(blk + 4 * i, block[i]);
             PUT_32BIT_MSB_FIRST(blk + 4 * i, block[i]);
@@ -905,7 +905,7 @@ static void aes_sdctr_sw(unsigned char *blk, int len, AESContext *ctx)
             ENCLASTROUND;
             ENCLASTROUND;
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 	for (i = 0; i < 4; i++) {
 	for (i = 0; i < 4; i++) {
             tmp = GET_32BIT_MSB_FIRST(blk + 4 * i);
             tmp = GET_32BIT_MSB_FIRST(blk + 4 * i);
@@ -956,7 +956,7 @@ static void aes_decrypt_cbc_sw(unsigned char *blk, int len, AESContext * ctx)
             DECLASTROUND;
             DECLASTROUND;
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 	for (i = 0; i < 4; i++) {
 	for (i = 0; i < 4; i++) {
             PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i] ^ block[i]);
             PUT_32BIT_MSB_FIRST(blk + 4 * i, iv[i] ^ block[i]);
@@ -1505,7 +1505,7 @@ static void aes_encrypt_cbc_ni(unsigned char *blk, int len, AESContext * ctx)
             enc = _mm_aesenclast_si128(enc, *(++keysched));
             enc = _mm_aesenclast_si128(enc, *(++keysched));
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 
 
         /* Store and go to next block */
         /* Store and go to next block */
@@ -1552,7 +1552,7 @@ static void aes_decrypt_cbc_ni(unsigned char *blk, int len, AESContext * ctx)
             dec = _mm_aesdeclast_si128(dec, *(++keysched));
             dec = _mm_aesdeclast_si128(dec, *(++keysched));
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 
 
         /* Xor data with IV */
         /* Xor data with IV */
@@ -1610,7 +1610,7 @@ static void aes_sdctr_ni(unsigned char *blk, int len, AESContext *ctx)
             enc = _mm_aesenclast_si128(enc, *(++keysched));
             enc = _mm_aesenclast_si128(enc, *(++keysched));
             break;
             break;
           default:
           default:
-            assert(0);
+            unreachable("bad AES round count");
         }
         }
 
 
         /* Xor with block and store result */
         /* Xor with block and store result */
@@ -1725,7 +1725,7 @@ static void aes_setup_ni(AESContext * ctx,
         AES_256_Key_Expansion (key, keysched);
         AES_256_Key_Expansion (key, keysched);
         break;
         break;
       default:
       default:
-        assert(0);
+        unreachable("bad AES key length");
     }
     }
 
 
     /*
     /*
@@ -1742,7 +1742,7 @@ static void aes_setup_ni(AESContext * ctx,
         aes_inv_key_14(ctx);
         aes_inv_key_14(ctx);
         break;
         break;
       default:
       default:
-        assert(0);
+        unreachable("bad AES key length");
     }
     }
 }
 }
 
 
@@ -1750,7 +1750,7 @@ static void aes_setup_ni(AESContext * ctx,
 
 
 static void aes_setup_ni(AESContext * ctx, const unsigned char *key, int keylen)
 static void aes_setup_ni(AESContext * ctx, const unsigned char *key, int keylen)
 {
 {
-    assert(0);
+    unreachable("aes_setup_ni called when not compiled in");
 }
 }
 
 
 INLINE static bool supports_aes_ni()
 INLINE static bool supports_aes_ni()

+ 4 - 4
source/putty/sshcommon.c

@@ -342,12 +342,12 @@ static bool zombiechan_want_close(Channel *chan, bool sent_eof, bool rcvd_eof)
 
 
 void chan_remotely_opened_confirmation(Channel *chan)
 void chan_remotely_opened_confirmation(Channel *chan)
 {
 {
-    assert(0 && "this channel type should never receive OPEN_CONFIRMATION");
+    unreachable("this channel type should never receive OPEN_CONFIRMATION");
 }
 }
 
 
 void chan_remotely_opened_failure(Channel *chan, const char *errtext)
 void chan_remotely_opened_failure(Channel *chan, const char *errtext)
 {
 {
-    assert(0 && "this channel type should never receive OPEN_FAILURE");
+    unreachable("this channel type should never receive OPEN_FAILURE");
 }
 }
 
 
 bool chan_default_want_close(
 bool chan_default_want_close(
@@ -435,7 +435,7 @@ bool chan_no_change_window_size(
 
 
 void chan_no_request_response(Channel *chan, bool success)
 void chan_no_request_response(Channel *chan, bool success)
 {
 {
-    assert(0 && "this channel type should never send a want-reply request");
+    unreachable("this channel type should never send a want-reply request");
 }
 }
 
 
 /* ----------------------------------------------------------------------
 /* ----------------------------------------------------------------------
@@ -556,7 +556,7 @@ struct ssh_ttymodes get_ttymodes_from_conf(Seat *seat, Conf *conf)
                     ival = (atoi(sval) != 0);
                     ival = (atoi(sval) != 0);
                 break;
                 break;
               default:
               default:
-                assert(0 && "Bad mode->type");
+                unreachable("Bad mode->type");
             }
             }
 
 
             modes.have_mode[mode->opcode] = true;
             modes.have_mode[mode->opcode] = true;

+ 10 - 5
source/putty/sshdh.c

@@ -186,11 +186,16 @@ int dh_modulus_bit_size(const struct dh_ctx *ctx)
  */
  */
 void dh_cleanup(struct dh_ctx *ctx)
 void dh_cleanup(struct dh_ctx *ctx)
 {
 {
-    mp_free(ctx->x);
-    mp_free(ctx->e);
-    mp_free(ctx->p);
-    mp_free(ctx->g);
-    mp_free(ctx->q);
+    if (ctx->x)
+        mp_free(ctx->x);
+    if (ctx->e)
+        mp_free(ctx->e);
+    if (ctx->p)
+        mp_free(ctx->p);
+    if (ctx->g)
+        mp_free(ctx->g);
+    if (ctx->q)
+        mp_free(ctx->q);
     sfree(ctx);
     sfree(ctx);
 }
 }
 
 

+ 13 - 13
source/putty/sshecc.c

@@ -311,7 +311,7 @@ EdwardsPoint *eddsa_public(mp_int *private_key, const ssh_keyalg *alg)
     for (size_t i = 0; i < curve->fieldBytes; ++i)
     for (size_t i = 0; i < curve->fieldBytes; ++i)
         put_byte(h, mp_get_byte(private_key, i));
         put_byte(h, mp_get_byte(private_key, i));
 
 
-    unsigned char hash[extra->hash->hlen];
+    unsigned char hash[MAX_HASH_LEN];
     ssh_hash_final(h, hash);
     ssh_hash_final(h, hash);
 
 
     mp_int *exponent = eddsa_exponent_from_hash(
     mp_int *exponent = eddsa_exponent_from_hash(
@@ -826,7 +826,7 @@ static mp_int *ecdsa_signing_exponent_from_data(
     ptrlen data)
     ptrlen data)
 {
 {
     /* Hash the data being signed. */
     /* Hash the data being signed. */
-    unsigned char hash[extra->hash->hlen];
+    unsigned char hash[MAX_HASH_LEN];
     ssh_hash *h = ssh_hash_new(extra->hash);
     ssh_hash *h = ssh_hash_new(extra->hash);
     put_data(h, data.ptr, data.len);
     put_data(h, data.ptr, data.len);
     ssh_hash_final(h, hash);
     ssh_hash_final(h, hash);
@@ -919,7 +919,7 @@ static mp_int *eddsa_signing_exponent_from_data(
     ptrlen r_encoded, ptrlen data)
     ptrlen r_encoded, ptrlen data)
 {
 {
     /* Hash (r || public key || message) */
     /* Hash (r || public key || message) */
-    unsigned char hash[extra->hash->hlen];
+    unsigned char hash[MAX_HASH_LEN];
     ssh_hash *h = ssh_hash_new(extra->hash);
     ssh_hash *h = ssh_hash_new(extra->hash);
     put_data(h, r_encoded.ptr, r_encoded.len);
     put_data(h, r_encoded.ptr, r_encoded.len);
     put_epoint(h, ek->publicKey, ek->curve, true); /* omit string header */
     put_epoint(h, ek->publicKey, ek->curve, true); /* omit string header */
@@ -1055,7 +1055,7 @@ static void eddsa_sign(ssh_key *key, const void *data, int datalen,
      * First, we hash the private key integer (bare, little-endian)
      * First, we hash the private key integer (bare, little-endian)
      * into a hash generating 2*fieldBytes of output.
      * into a hash generating 2*fieldBytes of output.
      */
      */
-    unsigned char hash[extra->hash->hlen];
+    unsigned char hash[MAX_HASH_LEN];
     ssh_hash *h = ssh_hash_new(extra->hash);
     ssh_hash *h = ssh_hash_new(extra->hash);
     for (size_t i = 0; i < ek->curve->fieldBytes; ++i)
     for (size_t i = 0; i < ek->curve->fieldBytes; ++i)
         put_byte(h, mp_get_byte(ek->privateKey, i));
         put_byte(h, mp_get_byte(ek->privateKey, i));
@@ -1269,15 +1269,15 @@ static void ssh_ecdhkex_w_setup(ecdh_key *dh)
 
 
 static void ssh_ecdhkex_m_setup(ecdh_key *dh)
 static void ssh_ecdhkex_m_setup(ecdh_key *dh)
 {
 {
-    unsigned char bytes[dh->curve->fieldBytes];
-    for (size_t i = 0; i < sizeof(bytes); ++i)
-        bytes[i] = random_byte();
-
-    bytes[0] &= 0xF8;
-    bytes[dh->curve->fieldBytes-1] &= 0x7F;
-    bytes[dh->curve->fieldBytes-1] |= 0x40;
-    dh->private = mp_from_bytes_le(make_ptrlen(bytes, dh->curve->fieldBytes));
-    smemclr(bytes, sizeof(bytes));
+    strbuf *bytes = strbuf_new();
+    for (size_t i = 0; i < dh->curve->fieldBytes; ++i)
+        put_byte(bytes, random_byte());
+
+    bytes->u[0] &= 0xF8;
+    bytes->u[bytes->len-1] &= 0x7F;
+    bytes->u[bytes->len-1] |= 0x40;
+    dh->private = mp_from_bytes_le(ptrlen_from_strbuf(bytes));
+    strbuf_free(bytes);
 
 
     dh->m_public = ecc_montgomery_multiply(dh->curve->m.G, dh->private);
     dh->m_public = ecc_montgomery_multiply(dh->curve->m.G, dh->private);
 }
 }

+ 1 - 1
source/putty/sshmac.c

@@ -32,7 +32,7 @@ static void ssh2_mac_prepare(ssh2_mac *mac, const void *blk, int len,
 void ssh2_mac_generate(ssh2_mac *mac, void *blk, int len, unsigned long seq)
 void ssh2_mac_generate(ssh2_mac *mac, void *blk, int len, unsigned long seq)
 {
 {
     ssh2_mac_prepare(mac, blk, len, seq);
     ssh2_mac_prepare(mac, blk, len, seq);
-    return ssh2_mac_genresult(mac, (unsigned char *)blk + len);
+    ssh2_mac_genresult(mac, (unsigned char *)blk + len);
 }
 }
 
 
 bool ssh2_mac_verify(
 bool ssh2_mac_verify(

+ 1 - 1
source/putty/sshmd5.c

@@ -311,7 +311,7 @@ void hmacmd5_do_hmac(struct hmacmd5_context *ctx,
 {
 {
     ssh2_mac_start(&ctx->mac);
     ssh2_mac_start(&ctx->mac);
     put_data(&ctx->mac, blk, len);
     put_data(&ctx->mac, blk, len);
-    return ssh2_mac_genresult(&ctx->mac, hmac);
+    ssh2_mac_genresult(&ctx->mac, hmac);
 }
 }
 
 
 const struct ssh2_macalg ssh_hmac_md5 = {
 const struct ssh2_macalg ssh_hmac_md5 = {

+ 1 - 1
source/putty/sshpubk.c

@@ -1478,7 +1478,7 @@ void ssh2_write_pubkey(FILE *fp, const char *comment,
         fprintf(fp, "%s\n", buffer);
         fprintf(fp, "%s\n", buffer);
         sfree(buffer);
         sfree(buffer);
     } else {
     } else {
-        assert(0 && "Bad key type in ssh2_write_pubkey");
+        unreachable("Bad key type in ssh2_write_pubkey");
     }
     }
 }
 }
 
 

+ 2 - 2
source/putty/sshrsa.c

@@ -727,9 +727,9 @@ static void oaep_mask(const struct ssh_hashalg *h, void *seed, int seedlen,
     while (datalen > 0) {
     while (datalen > 0) {
         int i, max = (datalen > h->hlen ? h->hlen : datalen);
         int i, max = (datalen > h->hlen ? h->hlen : datalen);
         ssh_hash *s;
         ssh_hash *s;
-        unsigned char hash[SSH2_KEX_MAX_HASH_LEN];
+        unsigned char hash[MAX_HASH_LEN];
 
 
-	assert(h->hlen <= SSH2_KEX_MAX_HASH_LEN);
+	assert(h->hlen <= MAX_HASH_LEN);
         s = ssh_hash_new(h);
         s = ssh_hash_new(h);
         put_data(s, seed, seedlen);
         put_data(s, seed, seedlen);
         put_uint32(s, count);
         put_uint32(s, count);

+ 1 - 1
source/putty/sshsh256.c

@@ -632,7 +632,7 @@ static void SHA256_ni(SHA256_State * s, const unsigned char *q, int len)
 
 
 static void SHA256_ni(SHA256_State * s, const unsigned char *q, int len)
 static void SHA256_ni(SHA256_State * s, const unsigned char *q, int len)
 {
 {
-    assert(0);
+    unreachable("SHA256_ni not compiled in");
 }
 }
 
 
 #endif  /* COMPILER_SUPPORTS_AES_NI */
 #endif  /* COMPILER_SUPPORTS_AES_NI */

+ 1 - 1
source/putty/sshsha.c

@@ -683,7 +683,7 @@ static void sha1_ni(SHA_State * s, const unsigned char *q, int len)
 
 
 static void sha1_ni(SHA_State * s, const unsigned char *q, int len)
 static void sha1_ni(SHA_State * s, const unsigned char *q, int len)
 {
 {
-    assert(0);
+    unreachable("sha1_ni not compiled in");
 }
 }
 
 
 bool supports_sha_ni(void)
 bool supports_sha_ni(void)

+ 4 - 5
source/putty/sshverstring.c

@@ -407,16 +407,15 @@ void ssh_verstring_handle_input(BinaryPacketProtocol *bpp)
 
 
 static PktOut *ssh_verstring_new_pktout(int type)
 static PktOut *ssh_verstring_new_pktout(int type)
 {
 {
-    assert(0 && "Should never try to send packets during SSH version "
-           "string exchange");
-    return NULL;
+    unreachable("Should never try to send packets during SSH version "
+                "string exchange");
 }
 }
 
 
 static void ssh_verstring_handle_output(BinaryPacketProtocol *bpp)
 static void ssh_verstring_handle_output(BinaryPacketProtocol *bpp)
 {
 {
     if (pq_peek(&bpp->out_pq)) {
     if (pq_peek(&bpp->out_pq)) {
-        assert(0 && "Should never try to send packets during SSH version "
-               "string exchange");
+        unreachable("Should never try to send packets during SSH version "
+                    "string exchange");
     }
     }
 }
 }
 
 

+ 1 - 1
source/putty/windows/winnet.c

@@ -784,7 +784,7 @@ void sk_addrcopy(SockAddr *addr, char *buf)
 	    memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
 	    memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,
 		   sizeof(struct in6_addr));
 		   sizeof(struct in6_addr));
 	else
 	else
-	    assert(false);
+	    unreachable("bad address family in sk_addrcopy");
     } else
     } else
 #endif
 #endif
     if (family == AF_INET) {
     if (family == AF_INET) {

+ 1 - 1
source/putty/windows/winpgntc.c

@@ -27,7 +27,7 @@ bool agent_exists(void)
 
 
 void agent_cancel_query(agent_pending_query *q)
 void agent_cancel_query(agent_pending_query *q)
 {
 {
-    assert(0 && "Windows agent queries are never asynchronous!");
+    unreachable("Windows agent queries are never asynchronous!");
 }
 }
 
 
 agent_pending_query *agent_query(
 agent_pending_query *agent_query(

+ 1 - 1
source/putty/x11fwd.c

@@ -663,7 +663,7 @@ void x11_format_auth_for_authfile(
         put_uint16(bs, 6); /* indicates IPv6 */
         put_uint16(bs, 6); /* indicates IPv6 */
         put_stringpl_xauth(bs, make_ptrlen(ipv6buf, 16));
         put_stringpl_xauth(bs, make_ptrlen(ipv6buf, 16));
     } else {
     } else {
-        assert(false && "Bad address type in x11_format_auth_for_authfile");
+        unreachable("Bad address type in x11_format_auth_for_authfile");
     }
     }
 
 
     {
     {