Deprecate char* functions on ByteBufferReader

Bug: webrtc:15661, webrtc:15665
Change-Id: Ia35b0092c219a89b5eba08d2e1a91be6e47dc746
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/328000
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41210}
diff --git a/api/transport/stun.cc b/api/transport/stun.cc
index 35a65fd..efbec13 100644
--- a/api/transport/stun.cc
+++ b/api/transport/stun.cc
@@ -41,7 +41,9 @@
   RTC_DCHECK(transaction_id.length() == cricket::kStunTransactionIdLength ||
              transaction_id.length() == cricket::kStunLegacyTransactionIdLength)
       << transaction_id.length();
-  ByteBufferReader reader(transaction_id.data(), transaction_id.size());
+  ByteBufferReader reader(rtc::MakeArrayView(
+      reinterpret_cast<const uint8_t*>(transaction_id.data()),
+      transaction_id.size()));
   uint32_t result = 0;
   uint32_t next;
   while (reader.ReadUInt32(&next)) {
@@ -912,7 +914,8 @@
     if (length() != SIZE_IP4) {
       return false;
     }
-    if (!buf->ReadBytes(reinterpret_cast<char*>(&v4addr), sizeof(v4addr))) {
+    if (!buf->ReadBytes(rtc::MakeArrayView(reinterpret_cast<uint8_t*>(&v4addr),
+                                           sizeof(v4addr)))) {
       return false;
     }
     rtc::IPAddress ipaddr(v4addr);
@@ -922,7 +925,8 @@
     if (length() != SIZE_IP6) {
       return false;
     }
-    if (!buf->ReadBytes(reinterpret_cast<char*>(&v6addr), sizeof(v6addr))) {
+    if (!buf->ReadBytes(rtc::MakeArrayView(reinterpret_cast<uint8_t*>(&v6addr),
+                                           sizeof(v6addr)))) {
       return false;
     }
     rtc::IPAddress ipaddr(v6addr);
@@ -1153,7 +1157,9 @@
 
 bool StunByteStringAttribute::Read(ByteBufferReader* buf) {
   bytes_ = new char[length()];
-  if (!buf->ReadBytes(bytes_, length())) {
+  RTC_CHECK(bytes_);
+  if (!buf->ReadBytes(
+          rtc::MakeArrayView(reinterpret_cast<uint8_t*>(bytes_), length()))) {
     return false;
   }
 
diff --git a/api/transport/stun_unittest.cc b/api/transport/stun_unittest.cc
index 96ad458..65891f3 100644
--- a/api/transport/stun_unittest.cc
+++ b/api/transport/stun_unittest.cc
@@ -35,7 +35,7 @@
   }
 
   void CheckStunTransactionID(const StunMessage& msg,
-                              const unsigned char* expectedID,
+                              const uint8_t* expectedID,
                               size_t length) {
     ASSERT_EQ(length, msg.transaction_id().size());
     ASSERT_EQ(length == kStunTransactionIdLength + 4, msg.IsLegacy());
@@ -65,10 +65,9 @@
   }
 
   size_t ReadStunMessageTestCase(StunMessage* msg,
-                                 const unsigned char* testcase,
+                                 const uint8_t* testcase,
                                  size_t size) {
-    const char* input = reinterpret_cast<const char*>(testcase);
-    rtc::ByteBufferReader buf(input, size);
+    rtc::ByteBufferReader buf(rtc::MakeArrayView(testcase, size));
     if (msg->Read(&buf)) {
       // Returns the size the stun message should report itself as being
       return (size - 20);
@@ -85,7 +84,7 @@
 // clang-format off
 // clang formatting doesn't respect inline comments.
 
-static const unsigned char kStunMessageWithIPv6MappedAddress[] = {
+static const uint8_t kStunMessageWithIPv6MappedAddress[] = {
   0x00, 0x01, 0x00, 0x18,  // message header
   0x21, 0x12, 0xa4, 0x42,  // transaction id
   0x29, 0x1f, 0xcd, 0x7c,
@@ -99,7 +98,7 @@
   0xfe, 0xe5, 0x00, 0xc3
 };
 
-static const unsigned char kStunMessageWithIPv4MappedAddress[] = {
+static const uint8_t kStunMessageWithIPv4MappedAddress[] = {
   0x01, 0x01, 0x00, 0x0c,   // binding response, length 12
   0x21, 0x12, 0xa4, 0x42,   // magic cookie
   0x29, 0x1f, 0xcd, 0x7c,   // transaction ID
@@ -111,7 +110,7 @@
 };
 
 // Test XOR-mapped IP addresses:
-static const unsigned char kStunMessageWithIPv6XorMappedAddress[] = {
+static const uint8_t kStunMessageWithIPv6XorMappedAddress[] = {
   0x01, 0x01, 0x00, 0x18,  // message header (binding response)
   0x21, 0x12, 0xa4, 0x42,  // magic cookie (rfc5389)
   0xe3, 0xa9, 0x46, 0xe1,  // transaction ID
@@ -125,7 +124,7 @@
   0xaa, 0xed, 0x01, 0xc3
 };
 
-static const unsigned char kStunMessageWithIPv4XorMappedAddress[] = {
+static const uint8_t kStunMessageWithIPv4XorMappedAddress[] = {
   0x01, 0x01, 0x00, 0x0c,  // message header (binding response)
   0x21, 0x12, 0xa4, 0x42,  // magic cookie
   0x29, 0x1f, 0xcd, 0x7c,  // transaction ID
@@ -137,7 +136,7 @@
 };
 
 // ByteString Attribute (username)
-static const unsigned char kStunMessageWithByteStringAttribute[] = {
+static const uint8_t kStunMessageWithByteStringAttribute[] = {
   0x00, 0x01, 0x00, 0x0c,
   0x21, 0x12, 0xa4, 0x42,
   0xe3, 0xa9, 0x46, 0xe1,
@@ -150,7 +149,7 @@
 
 // Message with an unknown but comprehensible optional attribute.
 // Parsing should succeed despite this unknown attribute.
-static const unsigned char kStunMessageWithUnknownAttribute[] = {
+static const uint8_t kStunMessageWithUnknownAttribute[] = {
   0x00, 0x01, 0x00, 0x14,
   0x21, 0x12, 0xa4, 0x42,
   0xe3, 0xa9, 0x46, 0xe1,
@@ -164,7 +163,7 @@
 };
 
 // ByteString Attribute (username) with padding byte
-static const unsigned char kStunMessageWithPaddedByteStringAttribute[] = {
+static const uint8_t kStunMessageWithPaddedByteStringAttribute[] = {
   0x00, 0x01, 0x00, 0x08,
   0x21, 0x12, 0xa4, 0x42,
   0xe3, 0xa9, 0x46, 0xe1,
@@ -175,7 +174,7 @@
 };
 
 // Message with an Unknown Attributes (uint16_t list) attribute.
-static const unsigned char kStunMessageWithUInt16ListAttribute[] = {
+static const uint8_t kStunMessageWithUInt16ListAttribute[] = {
   0x00, 0x01, 0x00, 0x0c,
   0x21, 0x12, 0xa4, 0x42,
   0xe3, 0xa9, 0x46, 0xe1,
@@ -187,7 +186,7 @@
 };
 
 // Error response message (unauthorized)
-static const unsigned char kStunMessageWithErrorAttribute[] = {
+static const uint8_t kStunMessageWithErrorAttribute[] = {
   0x01, 0x11, 0x00, 0x14,
   0x21, 0x12, 0xa4, 0x42,
   0x29, 0x1f, 0xcd, 0x7c,
@@ -205,7 +204,7 @@
 // The actual length in bytes of the invalid messages (including STUN header)
 static const int kRealLengthOfInvalidLengthTestCases = 32;
 
-static const unsigned char kStunMessageWithZeroLength[] = {
+static const uint8_t kStunMessageWithZeroLength[] = {
   0x00, 0x01, 0x00, 0x00,  // length of 0 (last 2 bytes)
   0x21, 0x12, 0xA4, 0x42,  // magic cookie
   '0', '1', '2', '3',      // transaction id
@@ -216,7 +215,7 @@
   0x21, 0x12, 0xA4, 0x53,
 };
 
-static const unsigned char kStunMessageWithExcessLength[] = {
+static const uint8_t kStunMessageWithExcessLength[] = {
   0x00, 0x01, 0x00, 0x55,  // length of 85
   0x21, 0x12, 0xA4, 0x42,  // magic cookie
   '0', '1', '2', '3',      // transaction id
@@ -227,7 +226,7 @@
   0x21, 0x12, 0xA4, 0x53,
 };
 
-static const unsigned char kStunMessageWithSmallLength[] = {
+static const uint8_t kStunMessageWithSmallLength[] = {
   0x00, 0x01, 0x00, 0x03,  // length of 3
   0x21, 0x12, 0xA4, 0x42,  // magic cookie
   '0', '1', '2', '3',      // transaction id
@@ -238,7 +237,7 @@
   0x21, 0x12, 0xA4, 0x53,
 };
 
-static const unsigned char kStunMessageWithBadHmacAtEnd[] = {
+static const uint8_t kStunMessageWithBadHmacAtEnd[] = {
   0x00, 0x01, 0x00, 0x14,  // message length exactly 20
   0x21, 0x12, 0xA4, 0x42,  // magic cookie
   '0', '1', '2', '3',      // transaction ID
@@ -253,7 +252,7 @@
 
 // RTCP packet, for testing we correctly ignore non stun packet types.
 // V=2, P=false, RC=0, Type=200, Len=6, Sender-SSRC=85, etc
-static const unsigned char kRtcpPacket[] = {
+static const uint8_t kRtcpPacket[] = {
   0x80, 0xc8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55,
   0xce, 0xa5, 0x18, 0x3a, 0x39, 0xcc, 0x7d, 0x09,
   0x23, 0xed, 0x19, 0x07, 0x00, 0x00, 0x01, 0x56,
@@ -266,7 +265,7 @@
 // Software name (response): "test vector" (without quotes)
 // Username:  "evtj:h6vY" (without quotes)
 // Password:  "VOkJxbRl1RmTxUk/WvJxBt" (without quotes)
-static const unsigned char kRfc5769SampleMsgTransactionId[] = {
+static const uint8_t kRfc5769SampleMsgTransactionId[] = {
   0xb7, 0xe7, 0xa7, 0x01, 0xbc, 0x34, 0xd6, 0x86, 0xfa, 0x87, 0xdf, 0xae
 };
 static const char kRfc5769SampleMsgClientSoftware[] = "STUN test client";
@@ -278,7 +277,7 @@
 static const rtc::SocketAddress kRfc5769SampleMsgIPv6MappedAddress(
     "2001:db8:1234:5678:11:2233:4455:6677", 32853);
 
-static const unsigned char kRfc5769SampleMsgWithAuthTransactionId[] = {
+static const uint8_t kRfc5769SampleMsgWithAuthTransactionId[] = {
   0x78, 0xad, 0x34, 0x33, 0xc6, 0xad, 0x72, 0xc0, 0x29, 0xda, 0x41, 0x2e
 };
 static const char kRfc5769SampleMsgWithAuthUsername[] =
@@ -289,7 +288,7 @@
 static const char kRfc5769SampleMsgWithAuthRealm[] = "example.org";
 
 // 2.1.  Sample Request
-static const unsigned char kRfc5769SampleRequest[] = {
+static const uint8_t kRfc5769SampleRequest[] = {
   0x00, 0x01, 0x00, 0x58,   //    Request type and message length
   0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,   // }
@@ -320,7 +319,7 @@
 };
 
 // 2.1.  Sample Request
-static const unsigned char kSampleRequestMI32[] = {
+static const uint8_t kSampleRequestMI32[] = {
   0x00, 0x01, 0x00, 0x48,   //    Request type and message length
   0x21, 0x12, 0xa4, 0x42,   //    Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,   // }
@@ -347,7 +346,7 @@
 };
 
 // 2.2.  Sample IPv4 Response
-static const unsigned char kRfc5769SampleResponse[] = {
+static const uint8_t kRfc5769SampleResponse[] = {
   0x01, 0x01, 0x00, 0x3c,  //     Response type and message length
   0x21, 0x12, 0xa4, 0x42,  //     Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,  // }
@@ -371,7 +370,7 @@
 };
 
 // 2.3.  Sample IPv6 Response
-static const unsigned char kRfc5769SampleResponseIPv6[] = {
+static const uint8_t kRfc5769SampleResponseIPv6[] = {
   0x01, 0x01, 0x00, 0x48,  //    Response type and message length
   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,  // }
@@ -398,7 +397,7 @@
 };
 
 // 2.4.  Sample Request with Long-Term Authentication
-static const unsigned char kRfc5769SampleRequestLongTermAuth[] = {
+static const uint8_t kRfc5769SampleRequestLongTermAuth[] = {
   0x00, 0x01, 0x00, 0x60,  //    Request type and message length
   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
   0x78, 0xad, 0x34, 0x33,  // }
@@ -433,7 +432,7 @@
 // Length parameter is changed to 0x38 from 0x58.
 // AddMessageIntegrity will add MI information and update the length param
 // accordingly.
-static const unsigned char kRfc5769SampleRequestWithoutMI[] = {
+static const uint8_t kRfc5769SampleRequestWithoutMI[] = {
   0x00, 0x01, 0x00, 0x38,  //    Request type and message length
   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,  // }
@@ -457,7 +456,7 @@
 
 // This HMAC differs from the RFC 5769 SampleRequest message. This differs
 // because spec uses 0x20 for the padding where as our implementation uses 0.
-static const unsigned char kCalculatedHmac1[] = {
+static const uint8_t kCalculatedHmac1[] = {
   0x79, 0x07, 0xc2, 0xd2,  // }
   0xed, 0xbf, 0xea, 0x48,  // }
   0x0e, 0x4c, 0x76, 0xd8,  // }  HMAC-SHA1 fingerprint
@@ -469,14 +468,14 @@
 // above since the sum is computed including header
 // and the header is different since the message is shorter
 // than when MESSAGE-INTEGRITY is used.
-static const unsigned char kCalculatedHmac1_32[] = {
+static const uint8_t kCalculatedHmac1_32[] = {
   0xda, 0x39, 0xde, 0x5d,  // }
 };
 
 // Length parameter is changed to 0x1c from 0x3c.
 // AddMessageIntegrity will add MI information and update the length param
 // accordingly.
-static const unsigned char kRfc5769SampleResponseWithoutMI[] = {
+static const uint8_t kRfc5769SampleResponseWithoutMI[] = {
   0x01, 0x01, 0x00, 0x1c,  //    Response type and message length
   0x21, 0x12, 0xa4, 0x42,  //    Magic cookie
   0xb7, 0xe7, 0xa7, 0x01,  // }
@@ -493,7 +492,7 @@
 
 // This HMAC differs from the RFC 5769 SampleResponse message. This differs
 // because spec uses 0x20 for the padding where as our implementation uses 0.
-static const unsigned char kCalculatedHmac2[] = {
+static const uint8_t kCalculatedHmac2[] = {
   0x5d, 0x6b, 0x58, 0xbe,  // }
   0xad, 0x94, 0xe0, 0x7e,  // }
   0xef, 0x0d, 0xfc, 0x12,  // }  HMAC-SHA1 fingerprint
@@ -505,7 +504,7 @@
 // above since the sum is computed including header
 // and the header is different since the message is shorter
 // than when MESSAGE-INTEGRITY is used.
-static const unsigned char kCalculatedHmac2_32[] = {
+static const uint8_t kCalculatedHmac2_32[] = {
   0xe7, 0x5c, 0xd3, 0x16,  // }
 };
 
@@ -513,14 +512,14 @@
 
 // A transaction ID without the 'magic cookie' portion
 // pjnat's test programs use this transaction ID a lot.
-const unsigned char kTestTransactionId1[] = {0x029, 0x01f, 0x0cd, 0x07c,
-                                             0x0ba, 0x058, 0x0ab, 0x0d7,
-                                             0x0f2, 0x041, 0x001, 0x000};
+const uint8_t kTestTransactionId1[] = {0x029, 0x01f, 0x0cd, 0x07c,
+                                       0x0ba, 0x058, 0x0ab, 0x0d7,
+                                       0x0f2, 0x041, 0x001, 0x000};
 
 // They use this one sometimes too.
-const unsigned char kTestTransactionId2[] = {0x0e3, 0x0a9, 0x046, 0x0e1,
-                                             0x07c, 0x000, 0x0c2, 0x062,
-                                             0x054, 0x008, 0x001, 0x000};
+const uint8_t kTestTransactionId2[] = {0x0e3, 0x0a9, 0x046, 0x0e1,
+                                       0x07c, 0x000, 0x0c2, 0x062,
+                                       0x054, 0x008, 0x001, 0x000};
 
 const in6_addr kIPv6TestAddress1 = {
     {{0x24, 0x01, 0xfa, 0x00, 0x00, 0x04, 0x10, 0x00, 0xbe, 0x30, 0x5b, 0xff,
@@ -743,7 +742,7 @@
 // kStunMessageWithIPv4MappedAddress, but with a different value where the
 // magic cookie was.
 TEST_F(StunTest, ReadLegacyMessage) {
-  unsigned char rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
+  uint8_t rfc3489_packet[sizeof(kStunMessageWithIPv4MappedAddress)];
   memcpy(rfc3489_packet, kStunMessageWithIPv4MappedAddress,
          sizeof(kStunMessageWithIPv4MappedAddress));
   // Overwrite the magic cookie here.
@@ -1122,10 +1121,9 @@
 }
 
 // Test that we fail to read messages with invalid lengths.
-void CheckFailureToRead(const unsigned char* testcase, size_t length) {
+void CheckFailureToRead(const uint8_t* testcase, size_t length) {
   StunMessage msg;
-  const char* input = reinterpret_cast<const char*>(testcase);
-  rtc::ByteBufferReader buf(input, length);
+  rtc::ByteBufferReader buf(rtc::MakeArrayView(testcase, length));
   ASSERT_FALSE(msg.Read(&buf));
 }
 
@@ -1228,9 +1226,7 @@
 // the RFC5769 test messages used include attributes not found in basic STUN.
 TEST_F(StunTest, AddMessageIntegrity) {
   IceMessage msg;
-  rtc::ByteBufferReader buf(
-      reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
-      sizeof(kRfc5769SampleRequestWithoutMI));
+  rtc::ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   EXPECT_TRUE(msg.Read(&buf));
   EXPECT_TRUE(msg.AddMessageIntegrity(kRfc5769SampleMsgPassword));
   const StunByteStringAttribute* mi_attr =
@@ -1246,9 +1242,7 @@
       kRfc5769SampleMsgPassword));
 
   IceMessage msg2;
-  rtc::ByteBufferReader buf2(
-      reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
-      sizeof(kRfc5769SampleResponseWithoutMI));
+  rtc::ByteBufferReader buf2(kRfc5769SampleResponseWithoutMI);
   EXPECT_TRUE(msg2.Read(&buf2));
   EXPECT_TRUE(msg2.AddMessageIntegrity(kRfc5769SampleMsgPassword));
   const StunByteStringAttribute* mi_attr2 =
@@ -1321,9 +1315,7 @@
 // Validate that we generate correct MESSAGE-INTEGRITY-32 attributes.
 TEST_F(StunTest, AddMessageIntegrity32) {
   IceMessage msg;
-  rtc::ByteBufferReader buf(
-      reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
-      sizeof(kRfc5769SampleRequestWithoutMI));
+  rtc::ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   EXPECT_TRUE(msg.Read(&buf));
   EXPECT_TRUE(msg.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
   const StunByteStringAttribute* mi_attr =
@@ -1339,9 +1331,7 @@
       kRfc5769SampleMsgPassword));
 
   IceMessage msg2;
-  rtc::ByteBufferReader buf2(
-      reinterpret_cast<const char*>(kRfc5769SampleResponseWithoutMI),
-      sizeof(kRfc5769SampleResponseWithoutMI));
+  rtc::ByteBufferReader buf2(kRfc5769SampleResponseWithoutMI);
   EXPECT_TRUE(msg2.Read(&buf2));
   EXPECT_TRUE(msg2.AddMessageIntegrity32(kRfc5769SampleMsgPassword));
   const StunByteStringAttribute* mi_attr2 =
@@ -1420,9 +1410,7 @@
 
 TEST_F(StunTest, AddFingerprint) {
   IceMessage msg;
-  rtc::ByteBufferReader buf(
-      reinterpret_cast<const char*>(kRfc5769SampleRequestWithoutMI),
-      sizeof(kRfc5769SampleRequestWithoutMI));
+  rtc::ByteBufferReader buf(kRfc5769SampleRequestWithoutMI);
   EXPECT_TRUE(msg.Read(&buf));
   EXPECT_TRUE(msg.AddFingerprint());
 
@@ -1435,7 +1423,7 @@
 // Sample "GTURN" relay message.
 // clang-format off
 // clang formatting doesn't respect inline comments.
-static const unsigned char kRelayMessage[] = {
+static const uint8_t kRelayMessage[] = {
   0x00, 0x01, 0x00, 88,    // message header
   0x21, 0x12, 0xA4, 0x42,  // magic cookie
   '0', '1', '2', '3',      // transaction id
@@ -1470,13 +1458,11 @@
 TEST_F(StunTest, ReadRelayMessage) {
   RelayMessage msg;
 
-  const char* input = reinterpret_cast<const char*>(kRelayMessage);
-  size_t size = sizeof(kRelayMessage);
-  rtc::ByteBufferReader buf(input, size);
+  rtc::ByteBufferReader buf(kRelayMessage);
   EXPECT_TRUE(msg.Read(&buf));
 
   EXPECT_EQ(STUN_BINDING_REQUEST, msg.type());
-  EXPECT_EQ(size - 20, msg.length());
+  EXPECT_EQ(sizeof(kRelayMessage) - 20, msg.length());
   EXPECT_EQ("0123456789ab", msg.transaction_id());
 
   RelayMessage msg2(STUN_BINDING_REQUEST, "0123456789ab");
@@ -1565,21 +1551,21 @@
 
   rtc::ByteBufferWriter out;
   EXPECT_TRUE(msg.Write(&out));
-  EXPECT_EQ(size, out.Length());
+  EXPECT_EQ(sizeof(kRelayMessage), out.Length());
   size_t len1 = out.Length();
   rtc::ByteBufferReader read_buf(out);
   std::string outstring;
   read_buf.ReadString(&outstring, len1);
-  EXPECT_EQ(0, memcmp(outstring.c_str(), input, len1));
+  EXPECT_EQ(0, memcmp(outstring.c_str(), kRelayMessage, len1));
 
   rtc::ByteBufferWriter out2;
   EXPECT_TRUE(msg2.Write(&out2));
-  EXPECT_EQ(size, out2.Length());
+  EXPECT_EQ(sizeof(kRelayMessage), out2.Length());
   size_t len2 = out2.Length();
   rtc::ByteBufferReader read_buf2(out2);
   std::string outstring2;
   read_buf2.ReadString(&outstring2, len2);
-  EXPECT_EQ(0, memcmp(outstring2.c_str(), input, len2));
+  EXPECT_EQ(0, memcmp(outstring2.c_str(), kRelayMessage, len2));
 }
 
 // Test that we can remove attribute from a message.
@@ -1826,7 +1812,7 @@
   ASSERT_EQ(size, out.Length());
 
   size_t read_size = ReadStunMessageTestCase(
-      &msg, reinterpret_cast<const unsigned char*>(out.Data()), out.Length());
+      &msg, reinterpret_cast<const uint8_t*>(out.Data()), out.Length());
   ASSERT_EQ(read_size + 20, size);
   CheckStunHeader(msg, STUN_BINDING_REQUEST, read_size);
   const StunUInt16ListAttribute* types =
@@ -1860,9 +1846,7 @@
   webrtc::metrics::Reset();  // Ensure counters start from zero.
   // Try the messages from RFC 5769.
   StunMessage message;
-  rtc::ByteBufferReader reader(
-      reinterpret_cast<const char*>(kRfc5769SampleRequest),
-      sizeof(kRfc5769SampleRequest));
+  rtc::ByteBufferReader reader(kRfc5769SampleRequest);
   EXPECT_TRUE(message.Read(&reader));
   EXPECT_EQ(message.ValidateMessageIntegrity(kRfc5769SampleMsgPassword),
             StunMessage::IntegrityStatus::kIntegrityOk);
diff --git a/modules/rtp_rtcp/source/rtp_packetizer_av1.cc b/modules/rtp_rtcp/source/rtp_packetizer_av1.cc
index 95dbaf3..859b529 100644
--- a/modules/rtp_rtcp/source/rtp_packetizer_av1.cc
+++ b/modules/rtp_rtcp/source/rtp_packetizer_av1.cc
@@ -74,8 +74,7 @@
 std::vector<RtpPacketizerAv1::Obu> RtpPacketizerAv1::ParseObus(
     rtc::ArrayView<const uint8_t> payload) {
   std::vector<Obu> result;
-  rtc::ByteBufferReader payload_reader(
-      reinterpret_cast<const char*>(payload.data()), payload.size());
+  rtc::ByteBufferReader payload_reader(payload);
   while (payload_reader.Length() > 0) {
     Obu obu;
     payload_reader.ReadUInt8(&obu.header);
diff --git a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
index 870f788..30bbbc5 100644
--- a/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
+++ b/modules/rtp_rtcp/source/video_rtp_depacketizer_av1.cc
@@ -188,8 +188,7 @@
   VectorObuInfo obu_infos;
   bool expect_continues_obu = false;
   for (rtc::ArrayView<const uint8_t> rtp_payload : rtp_payloads) {
-    rtc::ByteBufferReader payload(
-        reinterpret_cast<const char*>(rtp_payload.data()), rtp_payload.size());
+    rtc::ByteBufferReader payload(rtp_payload);
     uint8_t aggregation_header;
     if (!payload.ReadUInt8(&aggregation_header)) {
       RTC_DLOG(LS_WARNING)
diff --git a/p2p/base/port.cc b/p2p/base/port.cc
index ff11481..3069799 100644
--- a/p2p/base/port.cc
+++ b/p2p/base/port.cc
@@ -454,7 +454,8 @@
   // Parse the request message.  If the packet is not a complete and correct
   // STUN message, then ignore it.
   std::unique_ptr<IceMessage> stun_msg(new IceMessage());
-  rtc::ByteBufferReader buf(data, size);
+  rtc::ByteBufferReader buf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
   if (!stun_msg->Read(&buf) || (buf.Length() > 0)) {
     return false;
   }
diff --git a/p2p/base/pseudo_tcp.cc b/p2p/base/pseudo_tcp.cc
index eff86e8..5a5ce03 100644
--- a/p2p/base/pseudo_tcp.cc
+++ b/p2p/base/pseudo_tcp.cc
@@ -1191,7 +1191,8 @@
 
   // See http://www.freesoft.org/CIE/Course/Section4/8.htm for
   // parsing the options list.
-  rtc::ByteBufferReader buf(data, len);
+  rtc::ByteBufferReader buf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), len));
   while (buf.Length()) {
     uint8_t kind = TCP_OPT_EOL;
     buf.ReadUInt8(&kind);
diff --git a/p2p/base/stun_dictionary.cc b/p2p/base/stun_dictionary.cc
index bf6a1e4..4a54b65 100644
--- a/p2p/base/stun_dictionary.cc
+++ b/p2p/base/stun_dictionary.cc
@@ -80,7 +80,8 @@
 webrtc::RTCErrorOr<
     std::pair<uint64_t, std::deque<std::unique_ptr<StunAttribute>>>>
 StunDictionaryView::ParseDelta(const StunByteStringAttribute& delta) {
-  rtc::ByteBufferReader buf(delta.bytes(), delta.length());
+  rtc::ByteBufferReader buf(rtc::MakeArrayView(
+      reinterpret_cast<const uint8_t*>(delta.bytes()), delta.length()));
   uint16_t magic;
   if (!buf.ReadUInt16(&magic)) {
     return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
diff --git a/p2p/base/stun_request.cc b/p2p/base/stun_request.cc
index 5bf7dfe..fc5d43d 100644
--- a/p2p/base/stun_request.cc
+++ b/p2p/base/stun_request.cc
@@ -202,7 +202,8 @@
 
   // Parse the STUN message and continue processing as usual.
 
-  rtc::ByteBufferReader buf(data, size);
+  rtc::ByteBufferReader buf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
   std::unique_ptr<StunMessage> response(iter->second->msg_->CreateNew());
   if (!response->Read(&buf)) {
     RTC_LOG(LS_WARNING) << "Failed to read STUN response "
diff --git a/p2p/base/stun_server.cc b/p2p/base/stun_server.cc
index 7827a0b..d09ff4b 100644
--- a/p2p/base/stun_server.cc
+++ b/p2p/base/stun_server.cc
@@ -33,7 +33,8 @@
                           const rtc::SocketAddress& remote_addr,
                           const int64_t& /* packet_time_us */) {
   // Parse the STUN message; eat any messages that fail to parse.
-  rtc::ByteBufferReader bbuf(buf, size);
+  rtc::ByteBufferReader bbuf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(buf), size));
   StunMessage msg;
   if (!msg.Read(&bbuf)) {
     return;
diff --git a/p2p/base/turn_port.cc b/p2p/base/turn_port.cc
index 51529c8..a176272 100644
--- a/p2p/base/turn_port.cc
+++ b/p2p/base/turn_port.cc
@@ -991,7 +991,8 @@
                                     size_t size,
                                     int64_t packet_time_us) {
   // Read in the message, and process according to RFC5766, Section 10.4.
-  rtc::ByteBufferReader buf(data, size);
+  rtc::ByteBufferReader buf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
   TurnMessage msg;
   if (!msg.Read(&buf)) {
     RTC_LOG(LS_WARNING) << ToString()
diff --git a/p2p/base/turn_port_unittest.cc b/p2p/base/turn_port_unittest.cc
index 5c11ea3..93c4dff 100644
--- a/p2p/base/turn_port_unittest.cc
+++ b/p2p/base/turn_port_unittest.cc
@@ -1727,7 +1727,8 @@
     const StunByteStringAttribute* attr =
         msg->GetByteString(TestTurnCustomizer::STUN_ATTR_COUNTER);
     if (attr != nullptr && attr_counter_ != nullptr) {
-      rtc::ByteBufferReader buf(attr->bytes(), attr->length());
+      rtc::ByteBufferReader buf(rtc::MakeArrayView(
+          reinterpret_cast<const uint8_t*>(attr->bytes()), attr->length()));
       unsigned int val = ~0u;
       buf.ReadUInt32(&val);
       (*attr_counter_)++;
diff --git a/p2p/base/turn_server.cc b/p2p/base/turn_server.cc
index b362bfa..e2e1a7d 100644
--- a/p2p/base/turn_server.cc
+++ b/p2p/base/turn_server.cc
@@ -195,7 +195,8 @@
                                    const char* data,
                                    size_t size) {
   TurnMessage msg;
-  rtc::ByteBufferReader buf(data, size);
+  rtc::ByteBufferReader buf(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), size));
   if (!msg.Read(&buf) || (buf.Length() > 0)) {
     RTC_LOG(LS_WARNING) << "Received invalid STUN message";
     return;
diff --git a/p2p/stunprober/stun_prober.cc b/p2p/stunprober/stun_prober.cc
index f5abf43..4a62065 100644
--- a/p2p/stunprober/stun_prober.cc
+++ b/p2p/stunprober/stun_prober.cc
@@ -173,7 +173,8 @@
 void StunProber::Requester::Request::ProcessResponse(const char* buf,
                                                      size_t buf_len) {
   int64_t now = rtc::TimeMillis();
-  rtc::ByteBufferReader message(buf, buf_len);
+  rtc::ByteBufferReader message(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(buf), buf_len));
   cricket::StunMessage stun_response;
   if (!stun_response.Read(&message)) {
     // Invalid or incomplete STUN packet.
diff --git a/pc/sctp_utils.cc b/pc/sctp_utils.cc
index 54742c2..60ffdc7 100644
--- a/pc/sctp_utils.cc
+++ b/pc/sctp_utils.cc
@@ -64,7 +64,7 @@
   // Format defined at
   // http://tools.ietf.org/html/draft-jesup-rtcweb-data-protocol-04
 
-  rtc::ByteBufferReader buffer(payload.data<char>(), payload.size());
+  rtc::ByteBufferReader buffer(payload);
   uint8_t message_type;
   if (!buffer.ReadUInt8(&message_type)) {
     RTC_LOG(LS_WARNING) << "Could not read OPEN message type.";
diff --git a/pc/sctp_utils_unittest.cc b/pc/sctp_utils_unittest.cc
index 3e49824..9ef2068 100644
--- a/pc/sctp_utils_unittest.cc
+++ b/pc/sctp_utils_unittest.cc
@@ -35,7 +35,7 @@
     uint16_t label_length;
     uint16_t protocol_length;
 
-    rtc::ByteBufferReader buffer(packet.data<char>(), packet.size());
+    rtc::ByteBufferReader buffer(packet);
     ASSERT_TRUE(buffer.ReadUInt8(&message_type));
     EXPECT_EQ(0x03, message_type);
 
@@ -176,7 +176,7 @@
   webrtc::WriteDataChannelOpenAckMessage(&packet);
 
   uint8_t message_type;
-  rtc::ByteBufferReader buffer(packet.data<char>(), packet.size());
+  rtc::ByteBufferReader buffer(packet);
   ASSERT_TRUE(buffer.ReadUInt8(&message_type));
   EXPECT_EQ(0x02, message_type);
 
diff --git a/rtc_base/byte_buffer.cc b/rtc_base/byte_buffer.cc
index 7e808f2..a076f46 100644
--- a/rtc_base/byte_buffer.cc
+++ b/rtc_base/byte_buffer.cc
@@ -141,6 +141,9 @@
 }
 
 bool ByteBufferReader::ReadBytes(rtc::ArrayView<uint8_t> val) {
+  if (val.size() == 0) {
+    return true;
+  }
   return ReadBytes(val.data(), val.size());
 }
 
@@ -152,11 +155,13 @@
 bool ByteBufferReader::ReadBytes(uint8_t* val, size_t len) {
   if (len > Length()) {
     return false;
-  } else {
-    memcpy(val, bytes_ + start_, len);
-    start_ += len;
+  }
+  if (len == 0) {
     return true;
   }
+  memcpy(val, bytes_ + start_, len);
+  start_ += len;
+  return true;
 }
 
 bool ByteBufferReader::Consume(size_t size) {
diff --git a/rtc_base/byte_buffer.h b/rtc_base/byte_buffer.h
index 6a923ed..4a1e5f2 100644
--- a/rtc_base/byte_buffer.h
+++ b/rtc_base/byte_buffer.h
@@ -124,7 +124,8 @@
 // valid during the lifetime of the reader.
 class ByteBufferReader {
  public:
-  ByteBufferReader(const char* bytes, size_t len);
+  [[deprecated("Use ArrayView<uint8_t>")]] ByteBufferReader(const char* bytes,
+                                                            size_t len);
 
   explicit ByteBufferReader(
       rtc::ArrayView<const uint8_t> bytes ABSL_ATTRIBUTE_LIFETIME_BOUND);
@@ -160,7 +161,7 @@
   bool ReadBytes(rtc::ArrayView<uint8_t> val);
   // For backwards compatibility.
   // TODO(bugs.webrtc.org/15661): Deprecate and remove.
-  bool ReadBytes(char* val, size_t len);
+  [[deprecated("Read using ArrayView")]] bool ReadBytes(char* val, size_t len);
 
   // Appends next `len` bytes from the buffer to `val`. Returns false
   // if there is less than `len` bytes left.
diff --git a/rtc_base/byte_buffer_unittest.cc b/rtc_base/byte_buffer_unittest.cc
index 837fdad..f65299e 100644
--- a/rtc_base/byte_buffer_unittest.cc
+++ b/rtc_base/byte_buffer_unittest.cc
@@ -85,14 +85,14 @@
 
 TEST(ByteBufferTest, TestReadWriteBuffer) {
   ByteBufferWriter buffer;
-  ByteBufferReader read_buf(nullptr, 0);
+  ByteBufferReader read_buf(rtc::ArrayView<const uint8_t>(nullptr, 0));
   uint8_t ru8;
   EXPECT_FALSE(read_buf.ReadUInt8(&ru8));
 
   // Write and read uint8_t.
   uint8_t wu8 = 1;
   buffer.WriteUInt8(wu8);
-  ByteBufferReader read_buf1(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf1(buffer);
   EXPECT_TRUE(read_buf1.ReadUInt8(&ru8));
   EXPECT_EQ(wu8, ru8);
   EXPECT_EQ(0U, read_buf1.Length());
@@ -101,7 +101,7 @@
   // Write and read uint16_t.
   uint16_t wu16 = (1 << 8) + 1;
   buffer.WriteUInt16(wu16);
-  ByteBufferReader read_buf2(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf2(buffer);
   uint16_t ru16;
   EXPECT_TRUE(read_buf2.ReadUInt16(&ru16));
   EXPECT_EQ(wu16, ru16);
@@ -111,7 +111,7 @@
   // Write and read uint24.
   uint32_t wu24 = (3 << 16) + (2 << 8) + 1;
   buffer.WriteUInt24(wu24);
-  ByteBufferReader read_buf3(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf3(buffer);
   uint32_t ru24;
   EXPECT_TRUE(read_buf3.ReadUInt24(&ru24));
   EXPECT_EQ(wu24, ru24);
@@ -121,7 +121,7 @@
   // Write and read uint32_t.
   uint32_t wu32 = (4 << 24) + (3 << 16) + (2 << 8) + 1;
   buffer.WriteUInt32(wu32);
-  ByteBufferReader read_buf4(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf4(buffer);
   uint32_t ru32;
   EXPECT_TRUE(read_buf4.ReadUInt32(&ru32));
   EXPECT_EQ(wu32, ru32);
@@ -132,7 +132,7 @@
   uint32_t another32 = (8 << 24) + (7 << 16) + (6 << 8) + 5;
   uint64_t wu64 = (static_cast<uint64_t>(another32) << 32) + wu32;
   buffer.WriteUInt64(wu64);
-  ByteBufferReader read_buf5(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf5(buffer);
   uint64_t ru64;
   EXPECT_TRUE(read_buf5.ReadUInt64(&ru64));
   EXPECT_EQ(wu64, ru64);
@@ -142,7 +142,7 @@
   // Write and read string.
   std::string write_string("hello");
   buffer.WriteString(write_string);
-  ByteBufferReader read_buf6(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf6(buffer);
   std::string read_string;
   EXPECT_TRUE(read_buf6.ReadString(&read_string, write_string.size()));
   EXPECT_EQ(write_string, read_string);
@@ -152,9 +152,9 @@
   // Write and read bytes
   char write_bytes[] = "foo";
   buffer.WriteBytes(write_bytes, 3);
-  ByteBufferReader read_buf7(buffer.Data(), buffer.Length());
-  char read_bytes[3];
-  EXPECT_TRUE(read_buf7.ReadBytes(read_bytes, 3));
+  ByteBufferReader read_buf7(buffer);
+  uint8_t read_bytes[3];
+  EXPECT_TRUE(read_buf7.ReadBytes(read_bytes));
   for (int i = 0; i < 3; ++i) {
     EXPECT_EQ(write_bytes[i], read_bytes[i]);
   }
@@ -164,9 +164,9 @@
   // Write and read reserved buffer space
   char* write_dst = buffer.ReserveWriteBuffer(3);
   memcpy(write_dst, write_bytes, 3);
-  ByteBufferReader read_buf8(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf8(buffer);
   memset(read_bytes, 0, 3);
-  EXPECT_TRUE(read_buf8.ReadBytes(read_bytes, 3));
+  EXPECT_TRUE(read_buf8.ReadBytes(read_bytes));
   for (int i = 0; i < 3; ++i) {
     EXPECT_EQ(write_bytes[i], read_bytes[i]);
   }
@@ -179,7 +179,7 @@
   buffer.WriteUInt24(wu24);
   buffer.WriteUInt32(wu32);
   buffer.WriteUInt64(wu64);
-  ByteBufferReader read_buf9(buffer.Data(), buffer.Length());
+  ByteBufferReader read_buf9(buffer);
   EXPECT_TRUE(read_buf9.ReadUInt8(&ru8));
   EXPECT_EQ(wu8, ru8);
   EXPECT_TRUE(read_buf9.ReadUInt16(&ru16));
@@ -219,7 +219,7 @@
   size += 6;
   EXPECT_EQ(size, write_buffer.Length());
 
-  ByteBufferReader read_buffer(write_buffer.Data(), write_buffer.Length());
+  ByteBufferReader read_buffer(write_buffer);
   EXPECT_EQ(size, read_buffer.Length());
   uint64_t val1, val2, val3, val4, val5;
 
@@ -269,13 +269,13 @@
   ArrayView<const uint8_t> stored_view(buf, 3);
   ByteBufferReader read_buffer(stored_view);
   uint8_t result[] = {'1', '2', '3'};
-  EXPECT_TRUE(read_buffer.ReadBytes(rtc::ArrayView<uint8_t>(result, 2)));
+  EXPECT_TRUE(read_buffer.ReadBytes(rtc::MakeArrayView(result, 2)));
   EXPECT_EQ(result[0], 'a');
   EXPECT_EQ(result[1], 'b');
   EXPECT_EQ(result[2], '3');
-  EXPECT_TRUE(read_buffer.ReadBytes(rtc::ArrayView<uint8_t>(&result[2], 1)));
+  EXPECT_TRUE(read_buffer.ReadBytes(rtc::MakeArrayView(&result[2], 1)));
   EXPECT_EQ(result[2], 'c');
-  EXPECT_FALSE(read_buffer.ReadBytes(rtc::ArrayView<uint8_t>(result, 1)));
+  EXPECT_FALSE(read_buffer.ReadBytes(rtc::MakeArrayView(result, 1)));
 }
 
 }  // namespace rtc
diff --git a/rtc_base/server_socket_adapters.cc b/rtc_base/server_socket_adapters.cc
index 673083c..47c19cb 100644
--- a/rtc_base/server_socket_adapters.cc
+++ b/rtc_base/server_socket_adapters.cc
@@ -63,7 +63,8 @@
 void AsyncSocksProxyServerSocket::ProcessInput(char* data, size_t* len) {
   RTC_DCHECK(state_ < SS_CONNECT_PENDING);
 
-  ByteBufferReader response(data, *len);
+  ByteBufferReader response(
+      rtc::MakeArrayView(reinterpret_cast<const uint8_t*>(data), *len));
   if (state_ == SS_HELLO) {
     HandleHello(&response);
   } else if (state_ == SS_AUTH) {
diff --git a/rtc_base/socket_adapters.cc b/rtc_base/socket_adapters.cc
index 4ec93ae..f628929 100644
--- a/rtc_base/socket_adapters.cc
+++ b/rtc_base/socket_adapters.cc
@@ -520,7 +520,8 @@
 void AsyncSocksProxySocket::ProcessInput(char* data, size_t* len) {
   RTC_DCHECK(state_ < SS_TUNNEL);
 
-  ByteBufferReader response(data, *len);
+  ByteBufferReader response(
+      rtc::MakeArrayView(reinterpret_cast<uint8_t*>(data), *len));
 
   if (state_ == SS_HELLO) {
     uint8_t ver, method;
diff --git a/test/fuzzers/forward_error_correction_fuzzer.cc b/test/fuzzers/forward_error_correction_fuzzer.cc
index 04a459b..87b7685 100644
--- a/test/fuzzers/forward_error_correction_fuzzer.cc
+++ b/test/fuzzers/forward_error_correction_fuzzer.cc
@@ -34,7 +34,7 @@
       ForwardErrorCorrection::CreateFlexfec(kFecSsrc, kMediaSsrc);
 
   // Entropy from fuzzer.
-  rtc::ByteBufferReader fuzz_buffer(reinterpret_cast<const char*>(data), size);
+  rtc::ByteBufferReader fuzz_buffer(rtc::MakeArrayView(data, size));
 
   // Initial stream state.
   uint16_t media_seqnum;
@@ -75,8 +75,8 @@
   uint8_t packet_type;
   uint8_t packet_loss;
   while (true) {
-    if (!fuzz_buffer.ReadBytes(reinterpret_cast<char*>(packet_buffer),
-                               kPacketSize)) {
+    if (!fuzz_buffer.ReadBytes(
+            rtc::ArrayView<uint8_t>(packet_buffer, kPacketSize))) {
       return;
     }
     if (!fuzz_buffer.ReadUInt8(&reordering))
diff --git a/test/fuzzers/stun_parser_fuzzer.cc b/test/fuzzers/stun_parser_fuzzer.cc
index 6ca9eac..c8aad8c 100644
--- a/test/fuzzers/stun_parser_fuzzer.cc
+++ b/test/fuzzers/stun_parser_fuzzer.cc
@@ -15,14 +15,13 @@
 
 namespace webrtc {
 void FuzzOneInput(const uint8_t* data, size_t size) {
-  const char* message = reinterpret_cast<const char*>(data);
 
   // Normally we'd check the integrity first, but those checks are
   // fuzzed separately in stun_validator_fuzzer.cc. We still want to
   // fuzz this target since the integrity checks could be forged by a
   // malicious adversary who receives a call.
   std::unique_ptr<cricket::IceMessage> stun_msg(new cricket::IceMessage());
-  rtc::ByteBufferReader buf(message, size);
+  rtc::ByteBufferReader buf(rtc::MakeArrayView(data, size));
   stun_msg->Read(&buf);
   stun_msg->ValidateMessageIntegrity("");
 }