@@ -192,11 +192,10 @@ namespace internals {
192
192
// |type| is the major type as specified in RFC 7049 Section 2.1.
193
193
// |value| is the payload (e.g. for MajorType::UNSIGNED) or is the size
194
194
// (e.g. for BYTE_STRING).
195
- // If successful, returns the number of bytes read. Otherwise returns -1.
196
- // TODO(johannes): change return type to size_t and use 0 for error.
197
- int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
195
+ // If successful, returns the number of bytes read. Otherwise returns 0.
196
+ size_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
198
197
if (bytes.empty())
199
- return -1 ;
198
+ return 0 ;
200
199
uint8_t initial_byte = bytes[0];
201
200
*type = MajorType((initial_byte & kMajorTypeMask) >> kMajorTypeBitShift);
202
201
@@ -210,32 +209,32 @@ int8_t ReadTokenStart(span<uint8_t> bytes, MajorType* type, uint64_t* value) {
210
209
if (additional_information == kAdditionalInformation1Byte) {
211
210
// Values 24-255 are encoded with one initial byte, followed by the value.
212
211
if (bytes.size() < 2)
213
- return -1 ;
212
+ return 0 ;
214
213
*value = ReadBytesMostSignificantByteFirst<uint8_t>(bytes.subspan(1));
215
214
return 2;
216
215
}
217
216
if (additional_information == kAdditionalInformation2Bytes) {
218
217
// Values 256-65535: 1 initial byte + 2 bytes payload.
219
218
if (bytes.size() < 1 + sizeof(uint16_t))
220
- return -1 ;
219
+ return 0 ;
221
220
*value = ReadBytesMostSignificantByteFirst<uint16_t>(bytes.subspan(1));
222
221
return 3;
223
222
}
224
223
if (additional_information == kAdditionalInformation4Bytes) {
225
224
// 32 bit uint: 1 initial byte + 4 bytes payload.
226
225
if (bytes.size() < 1 + sizeof(uint32_t))
227
- return -1 ;
226
+ return 0 ;
228
227
*value = ReadBytesMostSignificantByteFirst<uint32_t>(bytes.subspan(1));
229
228
return 5;
230
229
}
231
230
if (additional_information == kAdditionalInformation8Bytes) {
232
231
// 64 bit uint: 1 initial byte + 8 bytes payload.
233
232
if (bytes.size() < 1 + sizeof(uint64_t))
234
- return -1 ;
233
+ return 0 ;
235
234
*value = ReadBytesMostSignificantByteFirst<uint64_t>(bytes.subspan(1));
236
235
return 9;
237
236
}
238
- return -1 ;
237
+ return 0 ;
239
238
}
240
239
241
240
// Writes the start of a token with |type|. The |value| may indicate the size,
@@ -777,10 +776,10 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) {
777
776
SetToken(CBORTokenTag::NULL_VALUE, 1);
778
777
return;
779
778
case kExpectedConversionToBase64Tag: { // BINARY
780
- const int8_t bytes_read = internals::ReadTokenStart(
779
+ const size_t bytes_read = internals::ReadTokenStart(
781
780
bytes_.subspan(status_.pos + 1), &token_start_type_,
782
781
&token_start_internal_value_);
783
- if (bytes_read < 0 || token_start_type_ != MajorType::BYTE_STRING ||
782
+ if (! bytes_read || token_start_type_ != MajorType::BYTE_STRING ||
784
783
token_start_internal_value_ > kMaxValidLength) {
785
784
SetError(Error::CBOR_INVALID_BINARY);
786
785
return;
@@ -830,47 +829,47 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) {
830
829
return;
831
830
}
832
831
default: {
833
- const int8_t token_start_length = internals::ReadTokenStart(
832
+ const size_t bytes_read = internals::ReadTokenStart(
834
833
bytes_.subspan(status_.pos), &token_start_type_,
835
834
&token_start_internal_value_);
836
- const bool success = token_start_length >= 0;
837
835
switch (token_start_type_) {
838
836
case MajorType::UNSIGNED: // INT32.
839
837
// INT32 is a signed int32 (int32 makes sense for the
840
838
// inspector_protocol, it's not a CBOR limitation), so we check
841
839
// against the signed max, so that the allowable values are
842
840
// 0, 1, 2, ... 2^31 - 1.
843
- if (!success || std::numeric_limits<int32_t>::max() <
844
- token_start_internal_value_) {
841
+ if (!bytes_read || std::numeric_limits<int32_t>::max() <
842
+ token_start_internal_value_) {
845
843
SetError(Error::CBOR_INVALID_INT32);
846
844
return;
847
845
}
848
- SetToken(CBORTokenTag::INT32, token_start_length );
846
+ SetToken(CBORTokenTag::INT32, bytes_read );
849
847
return;
850
848
case MajorType::NEGATIVE: { // INT32.
851
849
// INT32 is a signed int32 (int32 makes sense for the
852
850
// inspector_protocol, it's not a CBOR limitation); in CBOR, the
853
851
// negative values for INT32 are represented as NEGATIVE, that is, -1
854
852
// INT32 is represented as 1 << 5 | 0 (major type 1, additional info
855
- // value 0). The minimal allowed INT32 value in our protocol is
856
- // std::numeric_limits<int32_t>::min(). We check for it by directly
857
- // checking the payload against the maximal allowed signed (!) int32
858
- // value.
859
- if (!success || token_start_internal_value_ >
860
- std::numeric_limits<int32_t>::max()) {
853
+ // value 0).
854
+ // The represented allowed values range is -1 to -2^31.
855
+ // They are mapped into the encoded range of 0 to 2^31-1.
856
+ // We check the the payload in token_start_internal_value_ against
857
+ // that range (2^31-1 is also known as
858
+ // std::numeric_limits<int32_t>::max()).
859
+ if (!bytes_read || token_start_internal_value_ >
860
+ std::numeric_limits<int32_t>::max()) {
861
861
SetError(Error::CBOR_INVALID_INT32);
862
862
return;
863
863
}
864
- SetToken(CBORTokenTag::INT32, token_start_length );
864
+ SetToken(CBORTokenTag::INT32, bytes_read );
865
865
return;
866
866
}
867
867
case MajorType::STRING: { // STRING8.
868
- if (!success || token_start_internal_value_ > kMaxValidLength) {
868
+ if (!bytes_read || token_start_internal_value_ > kMaxValidLength) {
869
869
SetError(Error::CBOR_INVALID_STRING8);
870
870
return;
871
871
}
872
- uint64_t token_byte_length =
873
- token_start_internal_value_ + token_start_length;
872
+ uint64_t token_byte_length = token_start_internal_value_ + bytes_read;
874
873
if (token_byte_length > remaining_bytes) {
875
874
SetError(Error::CBOR_INVALID_STRING8);
876
875
return;
@@ -882,13 +881,12 @@ void CBORTokenizer::ReadNextToken(bool enter_envelope) {
882
881
case MajorType::BYTE_STRING: { // STRING16.
883
882
// Length must be divisible by 2 since UTF16 is 2 bytes per
884
883
// character, hence the &1 check.
885
- if (!success || token_start_internal_value_ > kMaxValidLength ||
884
+ if (!bytes_read || token_start_internal_value_ > kMaxValidLength ||
886
885
token_start_internal_value_ & 1) {
887
886
SetError(Error::CBOR_INVALID_STRING16);
888
887
return;
889
888
}
890
- uint64_t token_byte_length =
891
- token_start_internal_value_ + token_start_length;
889
+ uint64_t token_byte_length = token_start_internal_value_ + bytes_read;
892
890
if (token_byte_length > remaining_bytes) {
893
891
SetError(Error::CBOR_INVALID_STRING16);
894
892
return;
0 commit comments