Support CBOR encoding and decoding of negative integers
Added support for major type 1 for CBORValue, CBORReader, and
CBORWriter, and reduced the accepted range of major type 0 to
what fits in an int64_t. While the CBOR major types 0 and 1
together can represent integers in the range [-2^64, 2^64-1], to
reduce the C++ interface complexity we now represent them both in
an int64_t, with the range [-2^63, 2^63-1].
Bug: 786217
Change-Id: Ifee69efcddecea104532b99176d705b3d2801f41
Reviewed-on: https://chromium-review.googlesource.com/777807
Commit-Queue: Jun Choi <[email protected]>
Reviewed-by: Balazs Engedy <[email protected]>
Reviewed-by: Jeffrey Yasskin <[email protected]>
Cr-Commit-Position: refs/heads/master@{#525809}
diff --git a/content/browser/webauth/cbor/cbor_values.h b/content/browser/webauth/cbor/cbor_values.h
index 9b35fda..38db54e 100644
--- a/content/browser/webauth/cbor/cbor_values.h
+++ b/content/browser/webauth/cbor/cbor_values.h
@@ -5,6 +5,7 @@
#ifndef CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_VALUES_H_
#define CONTENT_BROWSER_WEBAUTH_CBOR_CBOR_VALUES_H_
+#include <stdint.h>
#include <string>
#include <tuple>
#include <vector>
@@ -18,7 +19,6 @@
// A class for Concise Binary Object Representation (CBOR) values.
// This does not support:
-// * Negative integers.
// * Floating-point numbers.
// * Indefinite-length encodings.
class CONTENT_EXPORT CBORValue {
@@ -43,13 +43,15 @@
// types are compared first. Thus the shortest key sorts first by the RFC
// rules (irrespective of the major type), but may not by CTAP rules.
bool operator()(const CBORValue& a, const CBORValue& b) const {
- DCHECK((a.is_unsigned() || a.is_string()) &&
- (b.is_unsigned() || b.is_string()));
+ DCHECK((a.is_integer() || a.is_string()) &&
+ (b.is_integer() || b.is_string()));
if (a.type() != b.type())
return a.type() < b.type();
switch (a.type()) {
case Type::UNSIGNED:
- return a.GetUnsigned() < b.GetUnsigned();
+ return a.GetInteger() < b.GetInteger();
+ case Type::NEGATIVE:
+ return a.GetInteger() > b.GetInteger();
case Type::STRING: {
const auto& a_str = a.GetString();
const size_t a_length = a_str.size();
@@ -74,6 +76,7 @@
enum class Type {
UNSIGNED = 0,
+ NEGATIVE = 1,
BYTE_STRING = 2,
STRING = 3,
ARRAY = 4,
@@ -93,7 +96,9 @@
CBORValue() noexcept; // A NONE value.
explicit CBORValue(Type type);
- explicit CBORValue(uint64_t in_unsigned);
+ explicit CBORValue(int integer_value);
+ explicit CBORValue(int64_t integer_value);
+ explicit CBORValue(uint64_t integer_value) = delete;
explicit CBORValue(const BinaryValue& in_bytes);
explicit CBORValue(BinaryValue&& in_bytes) noexcept;
@@ -125,6 +130,8 @@
bool is_type(Type type) const { return type == type_; }
bool is_none() const { return type() == Type::NONE; }
bool is_unsigned() const { return type() == Type::UNSIGNED; }
+ bool is_negative() const { return type() == Type::NEGATIVE; }
+ bool is_integer() const { return is_unsigned() || is_negative(); }
bool is_bytestring() const { return type() == Type::BYTE_STRING; }
bool is_string() const { return type() == Type::STRING; }
bool is_array() const { return type() == Type::ARRAY; }
@@ -132,8 +139,10 @@
bool is_simple() const { return type() == Type::SIMPLE_VALUE; }
// These will all fatally assert if the type doesn't match.
- const uint64_t& GetUnsigned() const;
SimpleValue GetSimpleValue() const;
+ const int64_t& GetInteger() const;
+ const int64_t& GetUnsigned() const;
+ const int64_t& GetNegative() const;
const BinaryValue& GetBytestring() const;
// Returned string may contain NUL characters.
const std::string& GetString() const;
@@ -145,7 +154,7 @@
union {
SimpleValue simple_value_;
- uint64_t unsigned_value_;
+ int64_t integer_value_;
BinaryValue bytestring_value_;
std::string string_value_;
ArrayValue array_value_;