BUG/MAJOR: quic: Wrong quic_max_available_room() returned value

Around limits for QUIC integer encoding, this functions could return
wrong values which lead to qc_build_frms() to prepare wrong CRYPTO (less chances)
or STREAM frames (more chances). qc_do_build_pkt() could build wrong packets
with bad CRYPTO/STREAM frames which could not be decoded by the peer.
In such a case ngtcp2 closes the connection with an ENCRYPTION_ERROR error
in a transport CONNECTION_CLOSE frame.
diff --git a/include/haproxy/xprt_quic.h b/include/haproxy/xprt_quic.h
index 5e66b54..48568e9 100644
--- a/include/haproxy/xprt_quic.h
+++ b/include/haproxy/xprt_quic.h
@@ -331,7 +331,8 @@
  * buffer with <sz> as size for a data field of bytes prefixed by its QUIC
  * variable-length (may be 0).
  * Also put in <*len_sz> the size of this QUIC variable-length.
- * So after returning from this function we have : <*len_sz> + <ret> = <sz>.
+ * So after returning from this function we have : <*len_sz> + <ret> <= <sz>
+ * (<*len_sz> = { max(i), i + ret <= <sz> }) .
  */
 static inline size_t max_available_room(size_t sz, size_t *len_sz)
 {
@@ -346,8 +347,22 @@
 	*len_sz = quic_int_getsize(ret);
 	/* Difference between the two sizes. Note that <sz_sz> >= <*len_sz>. */
 	diff = sz_sz - *len_sz;
-	if (unlikely(diff > 0))
-		ret += diff;
+	if (unlikely(diff > 0)) {
+		/* Let's try to take into an account remaining bytes.
+		 *
+		 *                  <----------------> <sz_sz>
+		 *  <--------------><-------->  +----> <max_int>
+		 *       <ret>       <len_sz>   |
+		 *  +---------------------------+-----------....
+		 *  <--------------------------------> <sz>
+		 */
+		size_t max_int = quic_max_int_by_size(*len_sz);
+
+		if (max_int + *len_sz <= sz)
+			ret = max_int;
+		else
+			ret = sz - diff;
+	}
 
 	return ret;
 }