if (ssl3->hs.msg_body.len == 0 && buf->len >= ssl3->hs.msg_len) {
if (ss->ssl3.hs.msg_body.len == 0 && buf->len >= ss->ssl3.hs.msg_len) {
ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf){    /*     * There may be a partial handshake message already in the handshake     * state. The incoming buffer may contain another portion, or a     * complete message or several messages followed by another portion.     *     * Each message is made contiguous before being passed to the actual     * message parser.     */    ssl3State *ssl3 = ss->ssl3;    sslBuffer *buf = &ssl3->hs.msgState; /* do not lose the original buffer pointer */    SECStatus rv;    PORT_Assert( ssl_HaveRecvBufLock(ss) );    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );    if (buf->buf == NULL) {	*buf = *origBuf;    }    while (buf->len > 0) {	if (ssl3->hs.header_bytes < 4) {	    uint8 t;	    t = *(buf->buf++);	    buf->len--;	    if (ssl3->hs.header_bytes++ == 0)		ssl3->hs.msg_type = (SSL3HandshakeType)t;	    else		ssl3->hs.msg_len = (ssl3->hs.msg_len << 8) + t;	    if (ssl3->hs.header_bytes < 4)	    	continue;#define MAX_HANDSHAKE_MSG_LEN 0x1ffff	/* 128k - 1 */	    if (ssl3->hs.msg_len > MAX_HANDSHAKE_MSG_LEN) {		(void)ssl3_DecodeError(ss);		PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);		return SECFailure;	    }#undef MAX_HANDSHAKE_MSG_LEN	    /* If msg_len is zero, be sure we fall through, 	    ** even if buf->len is zero. 	    */	    if (ssl3->hs.msg_len > 0) 	    	continue;	}	/*	 * Header has been gathered and there is at least one byte of new	 * data available for this message. If it can be done right out	 * of the original buffer, then use it from there.	 */	if (ssl3->hs.msg_body.len == 0 && buf->len >= ssl3->hs.msg_len) {	    /* handle it from input buffer */	    rv = ssl3_HandleHandshakeMessage(ss, buf->buf, ssl3->hs.msg_len);	    if (rv == SECFailure) {		/* This test wants to fall through on either		 * SECSuccess or SECWouldBlock.		 * ssl3_HandleHandshakeMessage MUST set the error code.		 */		return rv;	    }	    buf->buf += ssl3->hs.msg_len;	    buf->len -= ssl3->hs.msg_len;	    ssl3->hs.msg_len = 0;	    ssl3->hs.header_bytes = 0;	    if (rv != SECSuccess) { /* return if SECWouldBlock. */		return rv;	    }	} else {	    /* must be copied to msg_body and dealt with from there */	    unsigned int bytes;	    PORT_Assert(ssl3->hs.msg_body.len <= ssl3->hs.msg_len);	    bytes = PR_MIN(buf->len, ssl3->hs.msg_len - ssl3->hs.msg_body.len);	    /* Grow the buffer if needed */	    rv = sslBuffer_Grow(&ssl3->hs.msg_body, ssl3->hs.msg_len);	    if (rv != SECSuccess) {		/* sslBuffer_Grow has set a memory error code. */		return SECFailure;	    }	    PORT_Memcpy(ssl3->hs.msg_body.buf + ssl3->hs.msg_body.len,		        buf->buf, bytes);	    ssl3->hs.msg_body.len += bytes;	    buf->buf += bytes;	    buf->len -= bytes;	    PORT_Assert(ssl3->hs.msg_body.len <= ssl3->hs.msg_len);	    /* if we have a whole message, do it */	    if (ssl3->hs.msg_body.len == ssl3->hs.msg_len) {		rv = ssl3_HandleHandshakeMessage(		    ss, ssl3->hs.msg_body.buf, ssl3->hs.msg_len);		/*		 * XXX This appears to be wrong.  This error handling		 * should clean up after a SECWouldBlock return, like the		 * error handling used 40 lines before/above this one,		 */		if (rv != SECSuccess) {		    /* ssl3_HandleHandshakeMessage MUST set error code. */		    return rv;		}		ssl3->hs.msg_body.len = 0;		ssl3->hs.msg_len      = 0;		ssl3->hs.header_bytes = 0;	    } else {		PORT_Assert(buf->len == 0);		break;	    }	}    }	/* end loop */    origBuf->len = 0;	/* So ssl3_GatherAppDataRecord will keep looping. */    buf->buf = NULL;	/* not a leak. */    return SECSuccess;}