Add an /* up to */ comment to all subspan calls that may truncate.

bssl::Span::subspan, unlike std::span::subspan, is defined to truncate
the output length if the input is too short.

In order to allow for a migration to the standard behavior later, let's
already add some comments to mark the places that will need adjusting.

Change-Id: I5d37c730fd6ea131f3b3bfafe7ea0fe690906a22
Bug: 453872746
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/82928
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/d1_both.cc b/ssl/d1_both.cc
index 1ef97b9..a4a84b3 100644
--- a/ssl/d1_both.cc
+++ b/ssl/d1_both.cc
@@ -723,7 +723,7 @@
   // Pack as many handshake fragments into one record as we can. We stage the
   // fragments in the output buffer, to be sealed in-place.
   bool should_continue = false;
-  Span<uint8_t> fragments = out.subspan(prefix_len, max_in_len);
+  Span<uint8_t> fragments = out.subspan(prefix_len, /* up to */ max_in_len);
   CBB cbb;
   CBB_init_fixed(&cbb, fragments.data(), fragments.size());
   DTLSSentRecord sent_record;
diff --git a/ssl/encrypted_client_hello.cc b/ssl/encrypted_client_hello.cc
index cac0358..be01d9c 100644
--- a/ssl/encrypted_client_hello.cc
+++ b/ssl/encrypted_client_hello.cc
@@ -285,11 +285,21 @@
 
   // We assert with |uintptr_t| because the comparison would be UB if they
   // didn't alias.
+  // - |payload| must be contained in |extensions|.
   assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions) <=
          reinterpret_cast<uintptr_t>(payload.data()));
   assert(reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
                                      client_hello_outer->extensions_len) >=
          reinterpret_cast<uintptr_t>(payload.data() + payload.size()));
+  // - |extensions| must be contained in |client_hello|.
+  assert(reinterpret_cast<uintptr_t>(client_hello_outer->client_hello) <=
+         reinterpret_cast<uintptr_t>(client_hello_outer->extensions));
+  assert(reinterpret_cast<uintptr_t>(client_hello_outer->client_hello +
+                                     client_hello_outer->client_hello_len) >=
+         reinterpret_cast<uintptr_t>(client_hello_outer->extensions +
+                                     client_hello_outer->extensions_len));
+  // From this then follows that |aad|, being a copy of |client_hello|, contains
+  // the |payload| byte range as well.
   Span<uint8_t> payload_aad = Span(aad).subspan(
       payload.data() - client_hello_outer->client_hello, payload.size());
   OPENSSL_memset(payload_aad.data(), 0, payload_aad.size());
diff --git a/ssl/internal.h b/ssl/internal.h
index 0bcc083..e4cc29c 100644
--- a/ssl/internal.h
+++ b/ssl/internal.h
@@ -127,7 +127,7 @@
     span[0] = fixed_names[i];
     span = span.subspan(1);
   }
-  span = span.subspan(0, objects.size());
+  span = span.subspan(0, /* up to */ objects.size());
   for (size_t i = 0; i < span.size(); i++) {
     span[i] = objects[i].*name;
   }
diff --git a/ssl/s3_both.cc b/ssl/s3_both.cc
index b8c156b..898b549 100644
--- a/ssl/s3_both.cc
+++ b/ssl/s3_both.cc
@@ -99,7 +99,8 @@
   Span<const uint8_t> rest = msg;
   if (!SSL_is_quic(ssl) && ssl->s3->aead_write_ctx->is_null_cipher()) {
     while (!rest.empty()) {
-      Span<const uint8_t> chunk = rest.subspan(0, ssl->max_send_fragment);
+      Span<const uint8_t> chunk =
+          rest.subspan(0, /* up to */ ssl->max_send_fragment);
       rest = rest.subspan(chunk.size());
 
       if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) {
@@ -118,7 +119,7 @@
       size_t pending_len =
           ssl->s3->pending_hs_data ? ssl->s3->pending_hs_data->length : 0;
       Span<const uint8_t> chunk =
-          rest.subspan(0, ssl->max_send_fragment - pending_len);
+          rest.subspan(0, /* up to */ ssl->max_send_fragment - pending_len);
       assert(!chunk.empty());
       rest = rest.subspan(chunk.size());