Commit f0023516 authored by David Benjamin's avatar David Benjamin Committed by Commit Bot

Replace the CanConsume pattern in components/cbor.

Instead, combine the length check with the reading. This means we don't need
the iterator access to match CanConsume calls above it.

Bug: none
Change-Id: I541048c0f399d90650e87c3b995ac3a0ad9fccb6
Reviewed-on: https://chromium-review.googlesource.com/1195708
Commit-Queue: David Benjamin <davidben@chromium.org>
Reviewed-by: default avatarBalazs Engedy <engedy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587337}
parent 6d656b7c
...@@ -55,12 +55,8 @@ const char kUnknownError[] = "An unknown error occured."; ...@@ -55,12 +55,8 @@ const char kUnknownError[] = "An unknown error occured.";
} // namespace } // namespace
CBORReader::CBORReader(base::span<const uint8_t>::const_iterator begin, CBORReader::CBORReader(base::span<const uint8_t> data)
const base::span<const uint8_t>::const_iterator end) : rest_(data), error_code_(DecoderError::CBOR_NO_ERROR) {}
: begin_(begin),
it_(begin),
end_(end),
error_code_(DecoderError::CBOR_NO_ERROR) {}
CBORReader::~CBORReader() {} CBORReader::~CBORReader() {}
// static // static
...@@ -85,7 +81,7 @@ base::Optional<CBORValue> CBORReader::Read(base::span<uint8_t const> data, ...@@ -85,7 +81,7 @@ base::Optional<CBORValue> CBORReader::Read(base::span<uint8_t const> data,
size_t* num_bytes_consumed, size_t* num_bytes_consumed,
DecoderError* error_code_out, DecoderError* error_code_out,
int max_nesting_level) { int max_nesting_level) {
CBORReader reader(data.cbegin(), data.cend()); CBORReader reader(data);
base::Optional<CBORValue> decoded_cbor = base::Optional<CBORValue> decoded_cbor =
reader.DecodeCompleteDataItem(max_nesting_level); reader.DecodeCompleteDataItem(max_nesting_level);
...@@ -98,7 +94,7 @@ base::Optional<CBORValue> CBORReader::Read(base::span<uint8_t const> data, ...@@ -98,7 +94,7 @@ base::Optional<CBORValue> CBORReader::Read(base::span<uint8_t const> data,
if (error_code_out) if (error_code_out)
*error_code_out = error_code; *error_code_out = error_code;
*num_bytes_consumed = failed ? 0 : reader.num_bytes_consumed(); *num_bytes_consumed = failed ? 0 : data.size() - reader.num_bytes_remaining();
return decoded_cbor; return decoded_cbor;
} }
...@@ -137,13 +133,13 @@ base::Optional<CBORValue> CBORReader::DecodeCompleteDataItem( ...@@ -137,13 +133,13 @@ base::Optional<CBORValue> CBORReader::DecodeCompleteDataItem(
} }
base::Optional<CBORReader::DataItemHeader> CBORReader::DecodeDataItemHeader() { base::Optional<CBORReader::DataItemHeader> CBORReader::DecodeDataItemHeader() {
if (!CanConsume(1)) { const base::Optional<uint8_t> initial_byte = ReadByte();
if (!initial_byte) {
return base::nullopt; return base::nullopt;
} }
const uint8_t initial_byte = *it_++; const auto major_type = GetMajorType(initial_byte.value());
const auto major_type = GetMajorType(initial_byte); const uint8_t additional_info = GetAdditionalInfo(initial_byte.value());
const uint8_t additional_info = GetAdditionalInfo(initial_byte);
uint64_t value; uint64_t value;
if (!ReadVariadicLengthInteger(additional_info, &value)) if (!ReadVariadicLengthInteger(additional_info, &value))
...@@ -171,14 +167,16 @@ bool CBORReader::ReadVariadicLengthInteger(uint8_t additional_info, ...@@ -171,14 +167,16 @@ bool CBORReader::ReadVariadicLengthInteger(uint8_t additional_info,
return false; return false;
} }
if (!CanConsume(additional_bytes)) { const base::Optional<base::span<const uint8_t>> bytes =
ReadBytes(additional_bytes);
if (!bytes) {
return false; return false;
} }
uint64_t int_data = 0; uint64_t int_data = 0;
for (uint8_t i = 0; i < additional_bytes; ++i) { for (const uint8_t b : bytes.value()) {
int_data <<= 8; int_data <<= 8;
int_data |= *it_++; int_data |= b;
} }
*value = int_data; *value = int_data;
...@@ -235,12 +233,12 @@ base::Optional<CBORValue> CBORReader::DecodeToSimpleValue( ...@@ -235,12 +233,12 @@ base::Optional<CBORValue> CBORReader::DecodeToSimpleValue(
base::Optional<CBORValue> CBORReader::ReadStringContent( base::Optional<CBORValue> CBORReader::ReadStringContent(
const CBORReader::DataItemHeader& header) { const CBORReader::DataItemHeader& header) {
uint64_t num_bytes = header.value; uint64_t num_bytes = header.value;
if (!CanConsume(num_bytes)) { const base::Optional<base::span<const uint8_t>> bytes = ReadBytes(num_bytes);
if (!bytes) {
return base::nullopt; return base::nullopt;
} }
std::string cbor_string(it_, it_ + num_bytes); std::string cbor_string(bytes->begin(), bytes->end());
it_ += num_bytes;
return HasValidUTF8Format(cbor_string) return HasValidUTF8Format(cbor_string)
? base::make_optional<CBORValue>(CBORValue(std::move(cbor_string))) ? base::make_optional<CBORValue>(CBORValue(std::move(cbor_string)))
...@@ -250,13 +248,12 @@ base::Optional<CBORValue> CBORReader::ReadStringContent( ...@@ -250,13 +248,12 @@ base::Optional<CBORValue> CBORReader::ReadStringContent(
base::Optional<CBORValue> CBORReader::ReadByteStringContent( base::Optional<CBORValue> CBORReader::ReadByteStringContent(
const CBORReader::DataItemHeader& header) { const CBORReader::DataItemHeader& header) {
uint64_t num_bytes = header.value; uint64_t num_bytes = header.value;
if (!CanConsume(num_bytes)) { const base::Optional<base::span<const uint8_t>> bytes = ReadBytes(num_bytes);
if (!bytes) {
return base::nullopt; return base::nullopt;
} }
std::vector<uint8_t> cbor_byte_string(it_, it_ + num_bytes); std::vector<uint8_t> cbor_byte_string(bytes->begin(), bytes->end());
it_ += num_bytes;
return CBORValue(std::move(cbor_byte_string)); return CBORValue(std::move(cbor_byte_string));
} }
...@@ -309,12 +306,20 @@ base::Optional<CBORValue> CBORReader::ReadMapContent( ...@@ -309,12 +306,20 @@ base::Optional<CBORValue> CBORReader::ReadMapContent(
return CBORValue(std::move(cbor_map)); return CBORValue(std::move(cbor_map));
} }
bool CBORReader::CanConsume(uint64_t bytes) { base::Optional<uint8_t> CBORReader::ReadByte() {
if (base::checked_cast<uint64_t>(std::distance(it_, end_)) >= bytes) { const base::Optional<base::span<const uint8_t>> bytes = ReadBytes(1);
return true; return bytes ? base::make_optional(bytes.value()[0]) : base::nullopt;
} }
base::Optional<base::span<const uint8_t>> CBORReader::ReadBytes(
uint64_t num_bytes) {
if (base::strict_cast<uint64_t>(rest_.size()) < num_bytes) {
error_code_ = DecoderError::INCOMPLETE_CBOR_DATA; error_code_ = DecoderError::INCOMPLETE_CBOR_DATA;
return false; return base::nullopt;
}
const base::span<const uint8_t> ret = rest_.first(num_bytes);
rest_ = rest_.subspan(num_bytes);
return ret;
} }
bool CBORReader::CheckMinimalEncoding(uint8_t additional_bytes, bool CBORReader::CheckMinimalEncoding(uint8_t additional_bytes,
......
...@@ -97,8 +97,7 @@ class CBOR_EXPORT CBORReader { ...@@ -97,8 +97,7 @@ class CBOR_EXPORT CBORReader {
static const char* ErrorCodeToString(DecoderError error_code); static const char* ErrorCodeToString(DecoderError error_code);
private: private:
CBORReader(base::span<const uint8_t>::const_iterator it, explicit CBORReader(base::span<const uint8_t> data);
const base::span<const uint8_t>::const_iterator end);
// Encapsulates information extracted from the header of a CBOR data item, // Encapsulates information extracted from the header of a CBOR data item,
// which consists of the initial byte, and a variable-length-encoded integer // which consists of the initial byte, and a variable-length-encoded integer
...@@ -127,18 +126,17 @@ class CBOR_EXPORT CBORReader { ...@@ -127,18 +126,17 @@ class CBOR_EXPORT CBORReader {
int max_nesting_level); int max_nesting_level);
base::Optional<CBORValue> ReadMapContent(const DataItemHeader& header, base::Optional<CBORValue> ReadMapContent(const DataItemHeader& header,
int max_nesting_level); int max_nesting_level);
bool CanConsume(uint64_t bytes); base::Optional<uint8_t> ReadByte();
base::Optional<base::span<const uint8_t>> ReadBytes(uint64_t num_bytes);
bool HasValidUTF8Format(const std::string& string_data); bool HasValidUTF8Format(const std::string& string_data);
bool CheckOutOfOrderKey(const CBORValue& new_key, CBORValue::MapValue* map); bool CheckOutOfOrderKey(const CBORValue& new_key, CBORValue::MapValue* map);
bool CheckMinimalEncoding(uint8_t additional_bytes, uint64_t uint_data); bool CheckMinimalEncoding(uint8_t additional_bytes, uint64_t uint_data);
DecoderError GetErrorCode(); DecoderError GetErrorCode();
size_t num_bytes_consumed() const { return it_ - begin_; } size_t num_bytes_remaining() const { return rest_.size(); }
const base::span<const uint8_t>::const_iterator begin_; base::span<const uint8_t> rest_;
base::span<const uint8_t>::const_iterator it_;
const base::span<const uint8_t>::const_iterator end_;
DecoderError error_code_; DecoderError error_code_;
DISALLOW_COPY_AND_ASSIGN(CBORReader); DISALLOW_COPY_AND_ASSIGN(CBORReader);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment