Skip to content

Commit

Permalink
Bug 1139082 - Refactoring ssl_gtest to use filters, r=ekr
Browse files Browse the repository at this point in the history
  • Loading branch information
martinthomson committed Mar 3, 2015
1 parent 3d767f3 commit 9b972e6
Show file tree
Hide file tree
Showing 13 changed files with 1,290 additions and 694 deletions.
123 changes: 116 additions & 7 deletions external_tests/ssl_gtest/databuffer.h
Expand Up @@ -7,33 +7,142 @@
#ifndef databuffer_h__
#define databuffer_h__

#include <algorithm>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <iostream>

namespace nss_test {

class DataBuffer {
public:
DataBuffer() : data_(nullptr), len_(0) {}
DataBuffer(const uint8_t *data, size_t len) : data_(nullptr), len_(0) {
Assign(data, len);
}
explicit DataBuffer(const DataBuffer& other) : data_(nullptr), len_(0) {
Assign(other.data(), other.len());
}
~DataBuffer() { delete[] data_; }

void Assign(const uint8_t *data, size_t len) {
Allocate(len);
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
DataBuffer& operator=(const DataBuffer& other) {
if (&other != this) {
Assign(other.data(), other.len());
}
return *this;
}

void Allocate(size_t len) {
delete[] data_;
data_ = new unsigned char[len ? len : 1]; // Don't depend on new [0].
data_ = new uint8_t[len ? len : 1]; // Don't depend on new [0].
len_ = len;
}

void Truncate(size_t len) {
len_ = std::min(len_, len);
}

void Assign(const uint8_t* data, size_t len) {
Allocate(len);
memcpy(static_cast<void *>(data_), static_cast<const void *>(data), len);
}

// Write will do a new allocation and expand the size of the buffer if needed.
void Write(size_t index, const uint8_t* val, size_t count) {
if (index + count > len_) {
size_t newlen = index + count;
uint8_t* tmp = new uint8_t[newlen]; // Always > 0.
memcpy(static_cast<void*>(tmp),
static_cast<const void*>(data_), len_);
if (index > len_) {
memset(static_cast<void*>(tmp + len_), 0, index - len_);
}
delete[] data_;
data_ = tmp;
len_ = newlen;
}
memcpy(static_cast<void*>(data_ + index),
static_cast<const void*>(val), count);
}

void Write(size_t index, const DataBuffer& buf) {
Write(index, buf.data(), buf.len());
}

// Write an integer, also performing host-to-network order conversion.
void Write(size_t index, uint32_t val, size_t count) {
assert(count <= sizeof(uint32_t));
uint32_t nvalue = htonl(val);
auto* addr = reinterpret_cast<const uint8_t*>(&nvalue);
Write(index, addr + sizeof(uint32_t) - count, count);
}

// Starting at |index|, remove |remove| bytes and replace them with the
// contents of |buf|.
void Splice(const DataBuffer& buf, size_t index, size_t remove = 0) {
Splice(buf.data(), buf.len(), index, remove);
}

void Splice(const uint8_t* ins, size_t ins_len, size_t index, size_t remove = 0) {
uint8_t* old_value = data_;
size_t old_len = len_;

// The amount of stuff remaining from the tail of the old.
size_t tail_len = old_len - std::min(old_len, index + remove);
// The new length: the head of the old, the new, and the tail of the old.
len_ = index + ins_len + tail_len;
data_ = new uint8_t[len_ ? len_ : 1];

// The head of the old.
Write(0, old_value, std::min(old_len, index));
// Maybe a gap.
if (index > old_len) {
memset(old_value + index, 0, index - old_len);
}
// The new.
Write(index, ins, ins_len);
// The tail of the old.
if (tail_len > 0) {
Write(index + ins_len,
old_value + index + remove, tail_len);
}

delete[] old_value;
}

void Append(const DataBuffer& buf) { Splice(buf, len_); }

const uint8_t *data() const { return data_; }
uint8_t *data() { return data_; }
uint8_t* data() { return data_; }
size_t len() const { return len_; }
const bool empty() const { return len_ != 0; }
bool empty() const { return len_ == 0; }

private:
uint8_t *data_;
uint8_t* data_;
size_t len_;
};

#ifdef DEBUG
static const size_t kMaxBufferPrint = 10000;
#else
static const size_t kMaxBufferPrint = 32;
#endif

inline std::ostream& operator<<(std::ostream& stream, const DataBuffer& buf) {
stream << "[" << buf.len() << "] ";
for (size_t i = 0; i < buf.len(); ++i) {
if (i >= kMaxBufferPrint) {
stream << "...";
break;
}
stream << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<unsigned>(buf.data()[i]);
}
stream << std::dec;
return stream;
}

} // namespace nss_test

#endif
5 changes: 4 additions & 1 deletion external_tests/ssl_gtest/manifest.mn
@@ -1,4 +1,4 @@
#
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Expand All @@ -10,6 +10,9 @@ CPPSRCS = \
ssl_loopback_unittest.cc \
ssl_gtest.cc \
test_io.cc \
tls_agent.cc \
tls_connect.cc \
tls_filter.cc \
tls_parser.cc \
$(NULL)

Expand Down

0 comments on commit 9b972e6

Please sign in to comment.