1
0
mirror of https://github.com/square/okhttp.git synced 2025-08-08 23:42:08 +03:00

Don't crash processing fragmented web sockets messages (#5983)

* Don't crash processing fragmented web sockets messages

Closes: https://github.com/square/okhttp/issues/5965

* Update okhttp-testing-support/src/main/kotlin/okhttp3/TestUtil.kt

Co-Authored-By: Jake Wharton <jakew@google.com>

* Update okhttp-testing-support/src/main/kotlin/okhttp3/TestUtil.kt

Co-Authored-By: Jake Wharton <jakew@google.com>

* Update okhttp-testing-support/src/main/kotlin/okhttp3/TestUtil.kt

Co-Authored-By: Jake Wharton <jakew@google.com>

Co-authored-by: Jake Wharton <jakew@google.com>
This commit is contained in:
Jesse Wilson
2020-04-23 23:31:36 -04:00
committed by GitHub
parent ba21ef7e35
commit 3ca806c24b
4 changed files with 37 additions and 18 deletions

View File

@@ -21,6 +21,7 @@ import java.net.InetSocketAddress
import java.net.UnknownHostException
import java.util.Arrays
import okhttp3.internal.http2.Header
import okio.Buffer
import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeNoException
@@ -43,6 +44,31 @@ object TestUtil {
return String(array)
}
/**
* Okio buffers are internally implemented as a linked list of arrays. Usually this implementation
* detail is invisible to the caller, but subtle use of certain APIs may depend on these internal
* structures.
*
* We make such subtle calls in [okhttp3.internal.ws.MessageInflater] because we try to read a
* compressed stream that is terminated in a web socket frame even though the DEFLATE stream is
* not terminated.
*
* Use this method to create a degenerate Okio Buffer where each byte is in a separate segment of
* the internal list.
*/
@JvmStatic
fun fragmentBuffer(buffer: Buffer): Buffer {
// Write each byte into a new buffer, then clone it so that the segments are shared.
// Shared segments cannot be compacted so we'll get a long chain of short segments.
val result = Buffer()
while (!buffer.exhausted()) {
val box = Buffer()
box.write(buffer, 1)
result.write(box.copy(), 1)
}
return result
}
tailrec fun File.isDescendentOf(directory: File): Boolean {
val parentFile = parentFile ?: return false
if (parentFile == directory) return true