Beispiel #1
0
void testVarint(uint64_t val, std::initializer_list<uint8_t> bytes) {
  size_t n = bytes.size();
  ByteRange expected(&*bytes.begin(), n);

  {
    uint8_t buf[kMaxVarintLength64];
    EXPECT_EQ(expected.size(), encodeVarint(val, buf));
    EXPECT_TRUE(ByteRange(buf, expected.size()) == expected);
  }

  {
    ByteRange r = expected;
    uint64_t decoded = decodeVarint(r);
    EXPECT_TRUE(r.empty());
    EXPECT_EQ(val, decoded);
  }

  if (n < kMaxVarintLength64) {
    // Try from a full buffer too, different code path
    uint8_t buf[kMaxVarintLength64];
    memcpy(buf, &*bytes.begin(), n);

    uint8_t fills[] = {0, 0x7f, 0x80, 0xff};

    for (uint8_t fill : fills) {
      memset(buf + n, fill, kMaxVarintLength64 - n);
      ByteRange r(buf, kMaxVarintLength64);
      uint64_t decoded = decodeVarint(r);
      EXPECT_EQ(val, decoded);
      EXPECT_EQ(kMaxVarintLength64 - n, r.size());
    }
  }
}
Beispiel #2
0
bool ZSTDStreamCodec::doCompressStream(
    ByteRange& input,
    MutableByteRange& output,
    StreamCodec::FlushOp flushOp) {
  if (needReset_) {
    resetCCtx();
    needReset_ = false;
  }
  ZSTD_inBuffer in = {input.data(), input.size(), 0};
  ZSTD_outBuffer out = {output.data(), output.size(), 0};
  SCOPE_EXIT {
    input.uncheckedAdvance(in.pos);
    output.uncheckedAdvance(out.pos);
  };
  size_t const rc = zstdThrowIfError(ZSTD_compressStream2(
      cctx_.get(), &out, &in, zstdTranslateFlush(flushOp)));
  switch (flushOp) {
    case StreamCodec::FlushOp::NONE:
      return false;
    case StreamCodec::FlushOp::FLUSH:
    case StreamCodec::FlushOp::END:
      return rc == 0;
    default:
      throw std::invalid_argument("ZSTD: invalid FlushOp");
  }
}
void MatchPacketBuilder::buildIPv6_other(ByteList *msg,
                                         const ByteRange &data) const {
  addEthernet(msg);
  addIPv6(msg, data.size());

  msg->add(data.data(), data.size());
}
Beispiel #4
0
void writeFileAtomic(StringPiece filename, ByteRange data, mode_t permissions) {
  iovec iov;
  iov.iov_base = const_cast<unsigned char*>(data.data());
  iov.iov_len = data.size();
  auto rc = writeFileAtomicNoThrow(filename, &iov, 1, permissions);
  checkPosixError(rc, "writeFileAtomic() failed to update ", filename);
}
Beispiel #5
0
void IPAddressV6::setFromBinary(ByteRange bytes) {
    if (bytes.size() != 16) {
        throw IPAddressFormatException("Invalid IPv6 binary data: length must "
                                       "be 16 bytes, got ", bytes.size());
    }
    memcpy(&addr_.in6Addr_.s6_addr, bytes.data(), sizeof(in6_addr));
}
Beispiel #6
0
void MacAddress::setFromBinary(ByteRange value) {
  if (value.size() != SIZE) {
    throw invalid_argument(to<string>("MAC address must be 6 bytes "
                                      "long, got ", value.size()));
  }
  memcpy(bytes_ + 2, value.begin(), SIZE);
}
Beispiel #7
0
// public
bool IPAddress::inSubnetWithMask(const IPAddress& subnet, ByteRange mask)
    const {
  auto mkByteArray4 = [&]() -> ByteArray4 {
    ByteArray4 ba{{0}};
    std::memcpy(ba.data(), mask.begin(), std::min<size_t>(mask.size(), 4));
    return ba;
  };

  if (bitCount() == subnet.bitCount()) {
    if (isV4()) {
      return asV4().inSubnetWithMask(subnet.asV4(), mkByteArray4());
    } else {
      ByteArray16 ba{{0}};
      std::memcpy(ba.data(), mask.begin(), std::min<size_t>(mask.size(), 16));
      return asV6().inSubnetWithMask(subnet.asV6(), ba);
    }
  }

  // an IPv4 address can never belong in a IPv6 subnet unless the IPv6 is a 6to4
  // address and vice-versa
  if (isV6()) {
    const IPAddressV6& v6addr = asV6();
    const IPAddressV4& v4subnet = subnet.asV4();
    if (v6addr.is6To4()) {
      return v6addr.getIPv4For6To4().inSubnetWithMask(v4subnet, mkByteArray4());
    }
  } else if (subnet.isV6()) {
    const IPAddressV6& v6subnet = subnet.asV6();
    const IPAddressV4& v4addr = asV4();
    if (v6subnet.is6To4()) {
      return v4addr.inSubnetWithMask(v6subnet.getIPv4For6To4(), mkByteArray4());
    }
  }
  return false;
}
Beispiel #8
0
int Normalize::normOutput(ActionIterator *iter, ActionIterator *iterEnd) {
  if ((*iter)->type() != deprecated::AT_OUTPUT_V1::type())
    return 0;

  ByteRange valueRange = (*iter)->value();

  // Change port number from 16 to 32 bits.
  UInt32 port = normPortNumberV1(valueRange.data());
  UInt16 maxlen = *Big16_cast(valueRange.data() + 2);

  AT_OUTPUT output{port, maxlen};

  ptrdiff_t offset = buf_.offset(iter->data());
  ptrdiff_t endOffset = buf_.offset(iterEnd->data());

  buf_.insertUninitialized(valueRange.data(), 8);

  ActionRange range{{buf_.data() + offset, buf_.data() + endOffset + 8}};
  *iter = range.begin();
  *iterEnd = range.end();

  std::memcpy(RemoveConst_cast(iter->data()), &output, sizeof(output));

  assert((*iter)->type() == AT_OUTPUT::type());

  return 8;
}
Beispiel #9
0
// public
void IPAddressV4::setFromBinary(ByteRange bytes) {
  if (bytes.size() != 4) {
    throw IPAddressFormatException("Invalid IPv4 binary data: length must "
                                   "be 4 bytes, got ", bytes.size());
  }
  memcpy(&addr_.inAddr_.s_addr, bytes.data(), sizeof(in_addr));
}
Beispiel #10
0
Expected<IPAddress, IPAddressFormatError> IPAddress::tryFromBinary(
    ByteRange bytes) noexcept {
  // Check IPv6 first since it's our main protocol.
  if (bytes.size() == 16) {
    return IPAddressV6::tryFromBinary(bytes);
  } else if (bytes.size() == 4) {
    return IPAddressV4::tryFromBinary(bytes);
  } else {
    return makeUnexpected(IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY);
  }
}
Beispiel #11
0
// public static
IPAddress IPAddress::fromBinary(ByteRange bytes) {
  if (bytes.size() == 4) {
    return IPAddress(IPAddressV4::fromBinary(bytes));
  } else if (bytes.size() == 16) {
    return IPAddress(IPAddressV6::fromBinary(bytes));
  } else {
    string hexval = detail::Bytes::toHex(bytes.data(), bytes.size());
    throw IPAddressFormatException(
        sformat("Invalid address with hex value '{}'", hexval));
  }
}
Beispiel #12
0
bool RequestForward::validateInput(Validation *context) const {
  const ByteRange req = request();
  const Header *reqHeader = reinterpret_cast<const Header *>(req.data());

  if (reqHeader->length() != req.size()) {
    log_info("RequestForward inner request size is invalid");
    return false;
  }

  return true;
}
Beispiel #13
0
void RecordIOReader::Iterator::advanceToValid() {
  ByteRange record = findRecord(range_, fileId_).record;
  if (record.empty()) {
    recordAndPos_ = std::make_pair(ByteRange(), off_t(-1));
    range_.clear();  // at end
  } else {
    size_t skipped = record.begin() - range_.begin();
    DCHECK_GE(skipped, headerSize());
    skipped -= headerSize();
    range_.advance(skipped);
    recordAndPos_.first = record;
    recordAndPos_.second += skipped;
  }
}
Beispiel #14
0
RecordInfo findRecord(ByteRange searchRange,
                      ByteRange wholeRange,
                      uint32_t fileId) {
  static const uint32_t magic = Header::kMagic;
  static const ByteRange magicRange(reinterpret_cast<const uint8_t*>(&magic),
                                    sizeof(magic));

  DCHECK_GE(searchRange.begin(), wholeRange.begin());
  DCHECK_LE(searchRange.end(), wholeRange.end());

  const uint8_t* start = searchRange.begin();
  const uint8_t* end = std::min(searchRange.end(),
                                wholeRange.end() - sizeof(Header));
  // end-1: the last place where a Header could start
  while (start < end) {
    auto p = ByteRange(start, end + sizeof(magic)).find(magicRange);
    if (p == ByteRange::npos) {
      break;
    }

    start += p;
    auto r = validateRecord(ByteRange(start, wholeRange.end()), fileId);
    if (!r.record.empty()) {
      return r;
    }

    // No repeated prefix in magic, so we can do better than start++
    start += sizeof(magic);
  }

  return {0, {}};
}
Beispiel #15
0
bool PktFilter::match(ByteRange data, size_t totalLen) const {
  // Empty filter never matches.
  if (empty())
    return false;

  struct pcap_pkthdr hdr;
  hdr.ts.tv_sec = 0;
  hdr.ts.tv_usec = 0;
  hdr.caplen = UInt32_narrow_cast(data.size());
  hdr.len = UInt32_narrow_cast(totalLen);

  assert(prog_.bf_insns != nullptr);
  return pcap_offline_filter(&prog_, &hdr, data.data()) > 0;
}
Beispiel #16
0
void MatchPacketBuilder::buildTCPv4(ByteList *msg,
                                    const ByteRange &data) const {
  addEthernet(msg);
  addIPv4(msg, sizeof(pkt::TCPHdr) + data.size());

  pkt::TCPHdr tcp;
  std::memset(&tcp, 0, sizeof(tcp));
  tcp.srcPort = srcPort_;
  tcp.dstPort = dstPort_;
  tcp.cksum = pkt::Checksum({&tcp, sizeof(tcp)}, data);

  msg->add(&tcp, sizeof(tcp));
  msg->add(data.data(), data.size());
}
Beispiel #17
0
void MatchPacketBuilder::buildICMPv4(ByteList *msg,
                                     const ByteRange &data) const {
  addEthernet(msg);
  addIPv4(msg, sizeof(pkt::ICMPHdr) + data.size());

  pkt::ICMPHdr icmp;
  std::memset(&icmp, 0, sizeof(icmp));
  icmp.type = icmpType_;
  icmp.code = icmpCode_;
  icmp.cksum = pkt::Checksum({&icmp, sizeof(icmp)}, data);

  msg->add(&icmp, sizeof(icmp));
  msg->add(data.data(), data.size());
}
Beispiel #18
0
int HttpRange::checkAndInsert( ByteRange & range )
{
    if (( range.getBegin() == -1 )&&( range.getEnd() == -1 ))
        return -1;
    if ( m_lEntityLen > 0 )
    {
        if ( range.getBegin() >= m_lEntityLen )
            return 0;
        if ( range.check( m_lEntityLen ) )
            return -1;
    }
    m_list.push_back( new ByteRange( range ) );
    return 0;
}
Beispiel #19
0
bool ZSTDStreamCodec::doUncompressStream(
    ByteRange& input,
    MutableByteRange& output,
    StreamCodec::FlushOp) {
  if (needReset_) {
    resetDCtx();
    needReset_ = false;
  }
  ZSTD_inBuffer in = {input.data(), input.size(), 0};
  ZSTD_outBuffer out = {output.data(), output.size(), 0};
  SCOPE_EXIT {
    input.uncheckedAdvance(in.pos);
    output.uncheckedAdvance(out.pos);
  };
  size_t const rc =
      zstdThrowIfError(ZSTD_decompressStream(dctx_.get(), &out, &in));
  return rc == 0;
}
Beispiel #20
0
static size_t bufread_or_die(void *ptr, size_t size, size_t nmemb, ByteRange &buf)
{
	size_t read_count = buf.read(static_cast<char *>(ptr), size, nmemb);
	if (read_count < nmemb) {
		Output("Error: failed to read file (truncated)\n");
		abort();
	}
	return read_count;
}
Beispiel #21
0
void Normalize::normalizeQueueGetConfigReplyV1() {
  Header *hdr = header();

  size_t length = hdr->length();
  if (length < sizeof(QueueGetConfigReply)) {
    markInputInvalid("QueueGetConfigReply is too short");
    return;
  }

  if (hdr->version() == OFP_VERSION_1) {
    // Convert port number to 32-bits -- only for OpenFlow 1.0.
    UInt8 *ptr = buf_.mutableData() + sizeof(Header);
    PortNumber port = PortNumber::fromV1(*Big16_cast(ptr));
    std::memcpy(ptr, &port, sizeof(port));
  }

  // Convert QueueV1 to Queue.
  ByteRange data = SafeByteRange(buf_.mutableData(), buf_.size(),
                                 sizeof(QueueGetConfigReply));
  deprecated::QueueV1Range queues{data};

  Validation context;
  if (!queues.validateInput(&context)) {
    markInputInvalid("QueueGetConfigReply has invalid queues");
    return;
  }

  QueueList newQueues;
  for (auto &queue : queues) {
    QueueBuilder newQueue{queue};
    newQueues.add(newQueue);
  }

  // When converting to the regular `Queue` structure, we may exceed the max
  // message size of 65535.
  if (newQueues.size() > 65535 - sizeof(QueueGetConfigReply)) {
    markInputTooBig("QueueGetConfigReply is too big");
    return;
  }

  buf_.replace(data.begin(), data.end(), newQueues.data(), newQueues.size());
}
Model *BinaryConverter::Load(const std::string &shortname, const std::string &basepath)
{
	FileSystem::FileSource &fileSource = FileSystem::gameDataFiles;
	for (FileSystem::FileEnumerator files(fileSource, basepath, FileSystem::FileEnumerator::Recurse); !files.Finished(); files.Next()) {
		const FileSystem::FileInfo &info = files.Current();
		const std::string &fpath = info.GetPath();

		//check it's the expected type
		if (info.IsFile() && ends_with_ci(fpath, SGM_EXTENSION)) {
			//check it's the wanted name & load it
			const std::string name = info.GetName();

			if (shortname == name.substr(0, name.length() - SGM_EXTENSION.length())) {
				//curPath is used to find textures, patterns,
				//possibly other data files for this model.
				//Strip trailing slash
				m_curPath = info.GetDir();
				if (m_curPath[m_curPath.length()-1] == '/')
					m_curPath = m_curPath.substr(0, m_curPath.length()-1);

				RefCountedPtr<FileSystem::FileData> binfile = info.Read();
				if (binfile.Valid()) {
					Model* model(nullptr);
					size_t outSize(0);
					// decompress the loaded ByteRange in memory
					const ByteRange bin = binfile->AsByteRange();
					void *pDecompressedData = tinfl_decompress_mem_to_heap(&bin[0], bin.Size(), &outSize, 0);
					if (pDecompressedData) {
						// now parse in-memory representation as new ByteRange.
						Serializer::Reader rd(ByteRange(static_cast<char*>(pDecompressedData), outSize));
						model = CreateModel(rd);
						mz_free(pDecompressedData);
					}
					return model;
				}
			}
		}
	}

	throw (LoadingError("File not found"));
	return nullptr;
}
Beispiel #23
0
void MatchPacketBuilder::buildICMPv6(ByteList *msg,
                                     const ByteRange &data) const {
  const size_t len = sizeof(pkt::ICMPHdr) + data.size();

  addEthernet(msg);
  addIPv6(msg, len);

  pkt::IPv6PseudoHdr pseudoHdr;
  pseudoHdr.src = ipv6Src_;
  pseudoHdr.dst = ipv6Dst_;
  pseudoHdr.upperLength = UInt32_narrow_cast(len);
  pseudoHdr.nextHeader = ipProto_;

  pkt::ICMPHdr icmp;
  std::memset(&icmp, 0, sizeof(icmp));
  icmp.type = icmpType_;
  icmp.code = icmpCode_;
  icmp.cksum = pkt::Checksum({&pseudoHdr, sizeof(pseudoHdr)},
                             {&icmp, sizeof(icmp)}, data);

  msg->add(&icmp, sizeof(icmp));
  msg->add(data.data(), data.size());
}
Beispiel #24
0
RecordInfo validateRecord(ByteRange range, uint32_t fileId) {
  if (range.size() <= headerSize()) {  // records may not be empty
    return {0, {}};
  }
  const Header* header = reinterpret_cast<const Header*>(range.begin());
  range.advance(sizeof(Header));
  if (header->magic != Header::kMagic ||
      header->version != 0 ||
      header->hashFunction != 0 ||
      header->flags != 0 ||
      (fileId != 0 && header->fileId != fileId) ||
      header->dataLength > range.size()) {
    return {0, {}};
  }
  if (headerHash(*header) != header->headerHash) {
    return {0, {}};
  }
  range.reset(range.begin(), header->dataLength);
  if (dataHash(range) != header->dataHash) {
    return {0, {}};
  }
  return {header->fileId, range};
}
Beispiel #25
0
bool are_equal(const ByteRange& lhs, const ByteRange& rhs)
{
    return lhs.size() == rhs.size() && !memcmp(lhs.begin(), rhs.begin(), rhs.size());
}
Beispiel #26
0
void Normalize::normalizeQueueGetConfigReplyV2() {
  // Pad all queues to a multiple of 8. You can only get a queue whose size is
  // not a multiple of 8 if it contains an experimenter property with an
  // unusual length.

  Header *hdr = header();

  size_t length = hdr->length();
  if (length < sizeof(QueueGetConfigReply))
    return;

  ByteRange data = SafeByteRange(buf_.mutableData(), buf_.size(),
                                 sizeof(QueueGetConfigReply));

  size_t remaining = data.size();
  const UInt8 *ptr = data.data();

  ByteList newBuf;
  while (remaining > 16) {
    // Read 16-bit queue length from a potentially mis-aligned position.
    UInt16 queueLen = Big16_unaligned(ptr + 8);
    if (queueLen > remaining || queueLen < 16)
      return;
    // Copy queue header.
    newBuf.add(ptr, 16);

    // Iterate over properties and pad out the properties whose sizes are not
    // multiples of 8.
    const UInt8 *prop = ptr + 16;
    size_t propLeft = queueLen - 16;
    while (propLeft > 4) {
      UInt16 propSize = Big16_unaligned(prop + 2);
      if (propSize > propLeft || propSize < 4)
        return;
      newBuf.add(prop, propSize);
      if ((propSize % 8) != 0) {
        newBuf.addZeros(PadLength(propSize) - propSize);
      }
      prop += propSize;
      propLeft -= propSize;
    }

    if (propLeft != 0) {
      log_debug("normalizeQueueGetConfigReplyV2: propLeft != 0");
      return;
    }

    ptr += queueLen;
    assert(prop == ptr);

    remaining -= queueLen;
  }

  if (remaining != 0) {
    log_debug("normalizeQueueGetConfigReplyV2: remaining != 0");
    return;
  }

  // When padding the regular `Queue` structure, we may exceed the max
  // message size of 65535.
  if (newBuf.size() > 65535 - sizeof(QueueGetConfigReply)) {
    markInputTooBig("QueueGetConfigReply is too big");
    return;
  }

  buf_.replace(data.begin(), data.end(), newBuf.data(), newBuf.size());
}
Beispiel #27
0
ExperimenterBuilder::ExperimenterBuilder(const Experimenter *msg) : msg_{*msg} {
  ByteRange expData = msg->expData();
  setExpData(expData.data(), expData.size());
}
Beispiel #28
0
IOBuf::IOBuf(WrapBufferOp op, ByteRange br)
  : IOBuf(op, br.data(), br.size()) {
}
Beispiel #29
0
IOBuf::IOBuf(CopyBufferOp op, ByteRange br,
             uint64_t headroom, uint64_t minTailroom)
  : IOBuf(op, br.data(), br.size(), headroom, minTailroom) {
}
Beispiel #30
0
bool are_identical(const ByteRange& lhs, const ByteRange& rhs)
{
    return lhs.begin() == rhs.begin() && lhs.end() == rhs.end();
}