diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt index bc3732ec4989..44ed8bb9a7ce 100644 --- a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/http2/Http2Reader.kt @@ -266,6 +266,9 @@ class Http2Reader( when (id) { // SETTINGS_HEADER_TABLE_SIZE 1 -> { + if (value < 0) { + throw IOException("PROTOCOL_ERROR SETTINGS_HEADER_TABLE_SIZE > 2^31 - 1") + } } // SETTINGS_ENABLE_PUSH diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt index 5e8c5789691c..6971c444e7d4 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/http2/Http2Test.kt @@ -348,6 +348,22 @@ class Http2Test { ) } + @Test fun readSettingsFrameNegativeHeaderTableSize() { + writeMedium(frame, 6) // 2 for the code and 4 for the value + frame.writeByte(Http2.TYPE_SETTINGS) + frame.writeByte(FLAG_NONE) + frame.writeInt(0) // Settings are always on the connection stream 0. + frame.writeShort(1) // SETTINGS_HEADER_TABLE_SIZE + frame.writeInt(Int.MIN_VALUE) + assertFailsWith { + reader.nextFrame(requireSettings = false, BaseTestHandler()) + }.also { expected -> + assertThat(expected.message).isEqualTo( + "PROTOCOL_ERROR SETTINGS_HEADER_TABLE_SIZE > 2^31 - 1", + ) + } + } + @Test fun readSettingsFrameNegativeWindowSize() { writeMedium(frame, 6) // 2 for the code and 4 for the value frame.writeByte(Http2.TYPE_SETTINGS)