blob: 5605d8e7acda5d88233c2f612344a3aa270f0fd9 [file] [log] [blame]
[email protected]ca690b02013-04-17 10:38:431// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Bence Béky94658bf2018-05-11 19:22:585#include "net/spdy/spdy_buffer.h"
[email protected]ca690b02013-04-17 10:38:436
7#include <cstddef>
[email protected]08881f9a2013-07-12 19:30:318#include <cstring>
Bence Béky4e83f492018-05-13 23:14:259#include <string>
bnc3f6a8552017-05-17 13:40:3410#include <utility>
[email protected]ca690b02013-04-17 10:38:4311
[email protected]09a8d9172013-04-17 19:23:4912#include "base/bind.h"
Peter Kasting383640f52018-02-13 06:22:4013#include "base/callback.h"
[email protected]ca690b02013-04-17 10:38:4314#include "base/memory/ref_counted.h"
[email protected]ca690b02013-04-17 10:38:4315#include "net/base/io_buffer.h"
Ryan Hamiltonea4fa192022-04-12 18:30:4916#include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
[email protected]ca690b02013-04-17 10:38:4317#include "testing/gtest/include/gtest/gtest.h"
18
19namespace net {
20
21namespace {
22
23const char kData[] = "hello!\0hi.";
Daniel Cheng5feb16f2022-02-28 06:52:0724const size_t kDataSize = std::size(kData);
[email protected]ca690b02013-04-17 10:38:4325
26class SpdyBufferTest : public ::testing::Test {};
27
28// Make a string from the data remaining in |buffer|.
Bence Béky4e83f492018-05-13 23:14:2529std::string BufferToString(const SpdyBuffer& buffer) {
30 return std::string(buffer.GetRemainingData(), buffer.GetRemainingSize());
[email protected]ca690b02013-04-17 10:38:4331}
32
Ryan Hamilton0239aac2018-05-19 00:03:1333// Construct a SpdyBuffer from a spdy::SpdySerializedFrame and make sure its
34// data points to the frame's underlying data.
[email protected]ca690b02013-04-17 10:38:4335TEST_F(SpdyBufferTest, FrameConstructor) {
Ryan Hamilton0239aac2018-05-19 00:03:1336 SpdyBuffer buffer(std::make_unique<spdy::SpdySerializedFrame>(
bnc3f6a8552017-05-17 13:40:3437 const_cast<char*>(kData), kDataSize, false /* owns_buffer */));
[email protected]ca690b02013-04-17 10:38:4338
39 EXPECT_EQ(kData, buffer.GetRemainingData());
40 EXPECT_EQ(kDataSize, buffer.GetRemainingSize());
41}
42
43// Construct a SpdyBuffer from a const char*/size_t pair and make sure
44// it makes a copy of the data.
45TEST_F(SpdyBufferTest, DataConstructor) {
Bence Béky4e83f492018-05-13 23:14:2546 std::string data(kData, kDataSize);
[email protected]ca690b02013-04-17 10:38:4347 SpdyBuffer buffer(data.data(), data.size());
48 // This mutation shouldn't affect |buffer|'s data.
49 data[0] = 'H';
50
51 EXPECT_NE(kData, buffer.GetRemainingData());
52 EXPECT_EQ(kDataSize, buffer.GetRemainingSize());
Bence Béky4e83f492018-05-13 23:14:2553 EXPECT_EQ(std::string(kData, kDataSize), BufferToString(buffer));
[email protected]ca690b02013-04-17 10:38:4354}
55
[email protected]8a938fed2013-04-18 08:31:5856void IncrementBy(size_t* x,
57 SpdyBuffer::ConsumeSource expected_consume_source,
58 size_t delta,
59 SpdyBuffer::ConsumeSource consume_source) {
60 EXPECT_EQ(expected_consume_source, consume_source);
[email protected]09a8d9172013-04-17 19:23:4961 *x += delta;
62}
63
[email protected]ca690b02013-04-17 10:38:4364// Construct a SpdyBuffer and call Consume() on it, which should
[email protected]09a8d9172013-04-17 19:23:4965// update the remaining data pointer and size appropriately, as well
66// as calling the consume callbacks.
[email protected]ca690b02013-04-17 10:38:4367TEST_F(SpdyBufferTest, Consume) {
68 SpdyBuffer buffer(kData, kDataSize);
69
[email protected]09a8d9172013-04-17 19:23:4970 size_t x1 = 0;
71 size_t x2 = 0;
[email protected]8a938fed2013-04-18 08:31:5872 buffer.AddConsumeCallback(
Anna Malovafd90c3e2020-03-05 17:34:2873 base::BindRepeating(&IncrementBy, &x1, SpdyBuffer::CONSUME));
[email protected]8a938fed2013-04-18 08:31:5874 buffer.AddConsumeCallback(
Anna Malovafd90c3e2020-03-05 17:34:2875 base::BindRepeating(&IncrementBy, &x2, SpdyBuffer::CONSUME));
[email protected]09a8d9172013-04-17 19:23:4976
Bence Béky4e83f492018-05-13 23:14:2577 EXPECT_EQ(std::string(kData, kDataSize), BufferToString(buffer));
[email protected]ca690b02013-04-17 10:38:4378
79 buffer.Consume(5);
Bence Béky4e83f492018-05-13 23:14:2580 EXPECT_EQ(std::string(kData + 5, kDataSize - 5), BufferToString(buffer));
[email protected]09a8d9172013-04-17 19:23:4981 EXPECT_EQ(5u, x1);
82 EXPECT_EQ(5u, x2);
[email protected]ca690b02013-04-17 10:38:4383
84 buffer.Consume(kDataSize - 5);
85 EXPECT_EQ(0u, buffer.GetRemainingSize());
[email protected]09a8d9172013-04-17 19:23:4986 EXPECT_EQ(kDataSize, x1);
87 EXPECT_EQ(kDataSize, x2);
88}
89
90// Construct a SpdyBuffer and attach a ConsumeCallback to it. The
91// callback should be called when the SpdyBuffer is destroyed.
92TEST_F(SpdyBufferTest, ConsumeOnDestruction) {
93 size_t x = 0;
94
95 {
96 SpdyBuffer buffer(kData, kDataSize);
[email protected]8a938fed2013-04-18 08:31:5897 buffer.AddConsumeCallback(
Anna Malovafd90c3e2020-03-05 17:34:2898 base::BindRepeating(&IncrementBy, &x, SpdyBuffer::DISCARD));
[email protected]09a8d9172013-04-17 19:23:4999 }
100
101 EXPECT_EQ(kDataSize, x);
[email protected]ca690b02013-04-17 10:38:43102}
103
104// Make sure the IOBuffer returned by GetIOBufferForRemainingData()
105// points to the buffer's remaining data and isn't updated by
106// Consume().
107TEST_F(SpdyBufferTest, GetIOBufferForRemainingData) {
108 SpdyBuffer buffer(kData, kDataSize);
109
110 buffer.Consume(5);
111 scoped_refptr<IOBuffer> io_buffer = buffer.GetIOBufferForRemainingData();
112 size_t io_buffer_size = buffer.GetRemainingSize();
Bence Béky4e83f492018-05-13 23:14:25113 const std::string expectedData(kData + 5, kDataSize - 5);
114 EXPECT_EQ(expectedData, std::string(io_buffer->data(), io_buffer_size));
[email protected]ca690b02013-04-17 10:38:43115
116 buffer.Consume(kDataSize - 5);
Bence Béky4e83f492018-05-13 23:14:25117 EXPECT_EQ(expectedData, std::string(io_buffer->data(), io_buffer_size));
[email protected]ca690b02013-04-17 10:38:43118}
119
[email protected]08881f9a2013-07-12 19:30:31120// Make sure the IOBuffer returned by GetIOBufferForRemainingData()
121// outlives the buffer itself.
122TEST_F(SpdyBufferTest, IOBufferForRemainingDataOutlivesBuffer) {
Jeremy Roman0579ed62017-08-29 15:56:19123 auto buffer = std::make_unique<SpdyBuffer>(kData, kDataSize);
[email protected]08881f9a2013-07-12 19:30:31124 scoped_refptr<IOBuffer> io_buffer = buffer->GetIOBufferForRemainingData();
125 buffer.reset();
126
127 // This will cause a use-after-free error if |io_buffer| doesn't
128 // outlive |buffer|.
129 std::memcpy(io_buffer->data(), kData, kDataSize);
130}
131
[email protected]ca690b02013-04-17 10:38:43132} // namespace
133
134} // namespace net