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()); } } }
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()); }
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); }
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)); }
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); }
// 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; }
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; }
// 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)); }
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); } }
// 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)); } }
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; }
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; } }
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, {}}; }
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; }
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()); }
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()); }
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; }
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; }
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; }
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; }
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()); }
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}; }
bool are_equal(const ByteRange& lhs, const ByteRange& rhs) { return lhs.size() == rhs.size() && !memcmp(lhs.begin(), rhs.begin(), rhs.size()); }
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()); }
ExperimenterBuilder::ExperimenterBuilder(const Experimenter *msg) : msg_{*msg} { ByteRange expData = msg->expData(); setExpData(expData.data(), expData.size()); }
IOBuf::IOBuf(WrapBufferOp op, ByteRange br) : IOBuf(op, br.data(), br.size()) { }
IOBuf::IOBuf(CopyBufferOp op, ByteRange br, uint64_t headroom, uint64_t minTailroom) : IOBuf(op, br.data(), br.size(), headroom, minTailroom) { }
bool are_identical(const ByteRange& lhs, const ByteRange& rhs) { return lhs.begin() == rhs.begin() && lhs.end() == rhs.end(); }