Fix QPACK crash by unregistering observers with QpackHeaderTable.
QpackHeaderTable is owned by QpackDecoder, owned by QuicSpdySession. Each
observer is a QpackProgressiveDecoder, owned by QpackHeaderAccumulator, owned by
QuicSpdyStream. If a stream is deleted (local cancellation, reset received from
peer), then the observer must be deregistered with QpackHeaderTable in order to
avoid a crash.
gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 272562981
Change-Id: Ia49f2ef9aeeebcccb83405107f0224ee7d23694f
diff --git a/quic/core/qpack/qpack_header_table.cc b/quic/core/qpack/qpack_header_table.cc
index 30f15a5..7274ce4 100644
--- a/quic/core/qpack/qpack_header_table.cc
+++ b/quic/core/qpack/qpack_header_table.cc
@@ -197,6 +197,21 @@
observers_.insert({required_insert_count, observer});
}
+void QpackHeaderTable::UnregisterObserver(uint64_t required_insert_count,
+ Observer* observer) {
+ auto it = observers_.lower_bound(required_insert_count);
+ while (it != observers_.end() && it->first == required_insert_count) {
+ if (it->second == observer) {
+ observers_.erase(it);
+ return;
+ }
+ ++it;
+ }
+
+ // |observer| must have been registered.
+ QUIC_NOTREACHED();
+}
+
uint64_t QpackHeaderTable::draining_index(float draining_fraction) const {
DCHECK_LE(0.0, draining_fraction);
DCHECK_LE(draining_fraction, 1.0);