diff --git a/net/extras/preload_data/decoder.cc b/net/extras/preload_data/decoder.cc
index fc415ca72a6cc..b86110c656eab 100644
--- a/net/extras/preload_data/decoder.cc
+++ b/net/extras/preload_data/decoder.cc
@@ -4,13 +4,15 @@
 
 #include "net/extras/preload_data/decoder.h"
 
+#include "base/containers/span.h"
 #include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/notreached.h"
 
 namespace net::extras {
 
-PreloadDecoder::BitReader::BitReader(const uint8_t* bytes, size_t num_bits)
+PreloadDecoder::BitReader::BitReader(base::span<const uint8_t> bytes,
+                                     size_t num_bits)
     : bytes_(bytes), num_bits_(num_bits), num_bytes_((num_bits + 7) / 8) {}
 
 // Next sets |*out| to the next bit from the input. It returns false if no
@@ -20,7 +22,7 @@ bool PreloadDecoder::BitReader::Next(bool* out) {
     if (current_byte_index_ >= num_bytes_) {
       return false;
     }
-    current_byte_ = UNSAFE_TODO(bytes_[current_byte_index_++]);
+    current_byte_ = bytes_[current_byte_index_++];
     num_bits_used_ = 0;
   }
 
@@ -137,18 +139,18 @@ bool PreloadDecoder::BitReader::Seek(size_t offset) {
     return false;
   }
   current_byte_index_ = offset / 8;
-  current_byte_ = UNSAFE_TODO(bytes_[current_byte_index_++]);
+  current_byte_ = bytes_[current_byte_index_++];
   num_bits_used_ = offset % 8;
   return true;
 }
 
-PreloadDecoder::HuffmanDecoder::HuffmanDecoder(const uint8_t* tree,
+PreloadDecoder::HuffmanDecoder::HuffmanDecoder(base::span<const uint8_t> tree,
                                                size_t tree_bytes)
     : tree_(tree), tree_bytes_(tree_bytes) {}
 
 bool PreloadDecoder::HuffmanDecoder::Decode(PreloadDecoder::BitReader* reader,
                                             char* out) const {
-  const uint8_t* current = UNSAFE_TODO(&tree_[tree_bytes_ - 2]);
+  base::span<const uint8_t> current = tree_.subspan(tree_bytes_ - 2);
 
   for (;;) {
     bool bit;
@@ -156,7 +158,7 @@ bool PreloadDecoder::HuffmanDecoder::Decode(PreloadDecoder::BitReader* reader,
       return false;
     }
 
-    uint8_t b = UNSAFE_TODO(current[bit]);
+    uint8_t b = current[bit];
     if (b & 0x80) {
       *out = static_cast<char>(b & 0x7f);
       return true;
@@ -168,13 +170,13 @@ bool PreloadDecoder::HuffmanDecoder::Decode(PreloadDecoder::BitReader* reader,
       return false;
     }
 
-    current = UNSAFE_TODO(&tree_[offset]);
+    current = tree_.subspan(offset);
   }
 }
 
-PreloadDecoder::PreloadDecoder(const uint8_t* huffman_tree,
+PreloadDecoder::PreloadDecoder(base::span<const uint8_t>huffman_tree,
                                size_t huffman_tree_size,
-                               const uint8_t* trie,
+                               base::span<const uint8_t>trie,
                                size_t trie_bits,
                                size_t trie_root_position)
     : huffman_decoder_(huffman_tree, huffman_tree_size),
@@ -185,8 +187,8 @@ PreloadDecoder::PreloadDecoder(base::span<const uint8_t> huffman_tree,
                                base::span<const uint8_t> trie,
                                size_t trie_bits,
                                size_t trie_root_position)
-    : huffman_decoder_(huffman_tree.data(), huffman_tree.size()),
-      bit_reader_(trie.data(), trie_bits),
+    : huffman_decoder_(huffman_tree, huffman_tree.size()),
+      bit_reader_(trie, trie_bits),
       trie_root_position_(trie_root_position) {
   CHECK_LE((trie_bits + 7) / 8, trie.size());
 }
diff --git a/net/extras/preload_data/decoder.h b/net/extras/preload_data/decoder.h
index bdfddf5046438..9f9a31f9962c2 100644
--- a/net/extras/preload_data/decoder.h
+++ b/net/extras/preload_data/decoder.h
@@ -9,6 +9,7 @@
 
 #include <string>
 
+#include "base/memory/raw_span.h"
 #include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 
@@ -25,7 +26,7 @@ class PreloadDecoder {
   // BitReader is a class that allows a bytestring to be read bit-by-bit.
   class BitReader {
    public:
-    BitReader(const uint8_t* bytes, size_t num_bits);
+    BitReader(base::span<const uint8_t>bytes, size_t num_bits);
 
     BitReader(const BitReader&) = delete;
     BitReader& operator=(const BitReader&) = delete;
@@ -76,7 +77,7 @@ class PreloadDecoder {
     bool Seek(size_t offset);
 
    private:
-    const raw_ptr<const uint8_t, AllowPtrArithmetic> bytes_;
+    const base::raw_span<const uint8_t> bytes_;
     const size_t num_bits_;
     const size_t num_bytes_;
     // current_byte_index_ contains the current byte offset in |bytes_|.
@@ -98,7 +99,7 @@ class PreloadDecoder {
   // The tree is decoded by walking rather than a table-driven approach.
   class HuffmanDecoder {
    public:
-    HuffmanDecoder(const uint8_t* tree, size_t tree_bytes);
+    HuffmanDecoder(base::span<const uint8_t>tree, size_t tree_bytes);
 
     HuffmanDecoder(const HuffmanDecoder&) = delete;
     HuffmanDecoder& operator=(const HuffmanDecoder&) = delete;
@@ -106,13 +107,13 @@ class PreloadDecoder {
     bool Decode(PreloadDecoder::BitReader* reader, char* out) const;
 
    private:
-    const raw_ptr<const uint8_t, AllowPtrArithmetic> tree_;
+    const base::raw_span<const uint8_t> tree_;
     const size_t tree_bytes_;
   };
 
-  PreloadDecoder(const uint8_t* huffman_tree,
+  PreloadDecoder(base::span<const uint8_t>huffman_tree,
                  size_t huffman_tree_size,
-                 const uint8_t* trie,
+                 base::span<const uint8_t>trie,
                  size_t trie_bits,
                  size_t trie_root_position);
 
diff --git a/net/http/transport_security_state_unittest.cc b/net/http/transport_security_state_unittest.cc
index b786f0efa9335..fc3cf43b777f4 100644
--- a/net/http/transport_security_state_unittest.cc
+++ b/net/http/transport_security_state_unittest.cc
@@ -14,6 +14,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/span.h"
 #include "base/base64.h"
 #include "base/containers/to_vector.h"
 #include "base/files/file_path.h"
@@ -1570,7 +1571,7 @@ TEST_F(TransportSecurityStateTest, WriteSizeDecodeSize) {
     size_t position = writer.position();
     writer.Flush();
     ASSERT_NE(writer.bytes().data(), nullptr);
-    extras::PreloadDecoder::BitReader reader(writer.bytes().data(), position);
+    extras::PreloadDecoder::BitReader reader(writer.bytes(), position);
     size_t decoded_size;
     EXPECT_TRUE(reader.DecodeSize(&decoded_size));
     EXPECT_EQ(i, decoded_size);
@@ -1588,7 +1589,7 @@ TEST_F(TransportSecurityStateTest, DecodeSizeFour) {
   // 4 is encoded as 0b010. Shifted right to fill one byte, it is 0x02, with 5
   // bits of padding.
   uint8_t encoded = 0x02;
-  extras::PreloadDecoder::BitReader reader(&encoded, 8);
+  extras::PreloadDecoder::BitReader reader(base::span_from_ref(encoded), 8);
   for (size_t i = 0; i < 5; ++i) {
     bool unused;
     ASSERT_TRUE(reader.Next(&unused));
