Skip to content

Commit c929d3f

Browse files
Do not allow the reading of floats as integers and vice versa (#387)
1 parent c948271 commit c929d3f

17 files changed

Lines changed: 98 additions & 45 deletions

File tree

include/rfl/avro/Reader.hpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,29 @@ struct Reader {
8585
avro_value_get_boolean(_var.val_, &result);
8686
return (result != 0);
8787

88-
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
89-
std::is_integral<std::remove_cvref_t<T>>()) {
88+
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
9089
if (type == AVRO_DOUBLE) {
9190
double result = 0.0;
9291
const auto err = avro_value_get_double(_var.val_, &result);
9392
if (err) {
9493
return error("Could not cast to double.");
9594
}
9695
return static_cast<T>(result);
97-
} else if (type == AVRO_INT32) {
96+
} else if (type == AVRO_FLOAT) {
97+
float result = 0.0;
98+
const auto err = avro_value_get_float(_var.val_, &result);
99+
if (err) {
100+
return error("Could not cast to float.");
101+
}
102+
return static_cast<T>(result);
103+
} else {
104+
return rfl::error(
105+
"Could not cast to numeric value. The type must be float "
106+
"or double.");
107+
}
108+
109+
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
110+
if (type == AVRO_INT32) {
98111
int32_t result = 0;
99112
const auto err = avro_value_get_int(_var.val_, &result);
100113
if (err) {
@@ -108,17 +121,10 @@ struct Reader {
108121
return error("Could not cast to int64.");
109122
}
110123
return static_cast<T>(result);
111-
} else if (type == AVRO_FLOAT) {
112-
float result = 0.0;
113-
const auto err = avro_value_get_float(_var.val_, &result);
114-
if (err) {
115-
return error("Could not cast to float.");
116-
}
117-
return static_cast<T>(result);
124+
} else {
125+
return rfl::error(
126+
"Could not cast to numeric value. The type must be integral.");
118127
}
119-
return rfl::error(
120-
"Could not cast to numeric value. The type must be integral, float "
121-
"or double.");
122128

123129
} else if constexpr (internal::is_literal_v<T>) {
124130
int value = 0;

include/rfl/bson/Reader.hpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct Reader {
110110
return error(
111111
"Could not cast to string. The type must be UTF8 or symbol.");
112112
}
113+
113114
} else if constexpr (std::is_same<std::remove_cvref_t<T>,
114115
rfl::Bytestring>()) {
115116
if (btype != BSON_TYPE_BINARY) {
@@ -123,17 +124,23 @@ struct Reader {
123124
const auto data =
124125
internal::ptr_cast<const std::byte*>(value.v_binary.data);
125126
return rfl::Bytestring(data, data + value.v_binary.data_len);
127+
126128
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
127129
if (btype != BSON_TYPE_BOOL) {
128130
return error("Could not cast to boolean.");
129131
}
130132
return value.v_bool;
131-
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
132-
std::is_integral<std::remove_cvref_t<T>>()) {
133-
switch (btype) {
134-
case BSON_TYPE_DOUBLE:
135-
return static_cast<T>(value.v_double);
136133

134+
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
135+
if (btype != BSON_TYPE_DOUBLE) {
136+
return error(
137+
"Could not cast to numeric value. The type must be double, "
138+
"int32, int64 or date_time.");
139+
}
140+
return static_cast<T>(value.v_double);
141+
142+
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
143+
switch (btype) {
137144
case BSON_TYPE_INT32:
138145
return static_cast<T>(value.v_int32);
139146

@@ -145,9 +152,10 @@ struct Reader {
145152

146153
default:
147154
return error(
148-
"Could not cast to numeric value. The type must be double, "
155+
"Could not cast to numeric value. The type must be "
149156
"int32, int64 or date_time.");
150157
}
158+
151159
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bson_oid_t>()) {
152160
if (btype != BSON_TYPE_OID) {
153161
return error("Could not cast to OID.");

include/rfl/capnproto/Reader.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,22 @@ class Reader {
7878
}
7979
return _var.val_.as<bool>();
8080

81-
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
82-
std::is_integral<std::remove_cvref_t<T>>()) {
81+
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
82+
if (type != capnp::DynamicValue::FLOAT) {
83+
return error("Could not cast to float.");
84+
}
85+
return static_cast<T>(_var.val_.as<double>());
86+
87+
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
8388
switch (type) {
8489
case capnp::DynamicValue::INT:
8590
return static_cast<T>(_var.val_.as<int64_t>());
8691

8792
case capnp::DynamicValue::UINT:
8893
return static_cast<T>(_var.val_.as<uint64_t>());
8994

90-
case capnp::DynamicValue::FLOAT:
91-
return static_cast<T>(_var.val_.as<double>());
92-
9395
default:
94-
return error(
95-
"Could not cast to numeric value. The type must be integral, "
96-
"float or double.");
96+
return error("Could not cast to an integer.");
9797
}
9898

9999
} else if constexpr (internal::is_literal_v<T>) {

include/rfl/cbor/Reader.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Reader {
7171
return error("Could not cast to string.");
7272
}
7373
return _var.val_->as<std::string>();
74+
7475
} else if constexpr (std::is_same<std::remove_cvref_t<T>,
7576
rfl::Bytestring>()) {
7677
if (!_var.val_->is_byte_string()) {
@@ -79,25 +80,28 @@ class Reader {
7980
const auto vec = _var.val_->as<std::vector<uint8_t>>();
8081
const auto data = internal::ptr_cast<const std::byte*>(vec.data());
8182
return rfl::Bytestring(data, data + vec.size());
83+
8284
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
8385
if (!_var.val_->is_bool()) {
8486
return error("Could not cast to boolean.");
8587
}
8688
return _var.val_->as<bool>();
87-
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
88-
std::is_integral<std::remove_cvref_t<T>>()) {
89+
90+
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
8991
if (_var.val_->is_double()) {
9092
return static_cast<T>(_var.val_->as<double>());
9193
}
94+
return error("Could not cast to double.");
95+
96+
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
9297
if (_var.val_->is_int64()) {
9398
return static_cast<T>(_var.val_->as<int64_t>());
9499
}
95100
if (_var.val_->is_uint64()) {
96101
return static_cast<T>(_var.val_->as<uint64_t>());
97102
}
98-
return error(
99-
"Could not cast to numeric value. The type must be integral, "
100-
"float or double.");
103+
return error("Could not cast to integer.");
104+
101105
} else {
102106
static_assert(rfl::always_false_v<T>, "Unsupported type.");
103107
}

include/rfl/flexbuf/Reader.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct Reader {
7474
return error("Could not cast to a string.");
7575
}
7676
return std::string(_var.AsString().c_str());
77+
7778
} else if constexpr (std::is_same<std::remove_cvref_t<T>,
7879
rfl::Bytestring>()) {
7980
if (!_var.IsBlob()) {
@@ -82,21 +83,25 @@ struct Reader {
8283
const auto blob = _var.AsBlob();
8384
const auto data = internal::ptr_cast<const std::byte*>(blob.data());
8485
return rfl::Bytestring(data, data + blob.size());
86+
8587
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
8688
if (!_var.IsBool()) {
8789
return error("Could not cast to boolean.");
8890
}
8991
return _var.AsBool();
92+
9093
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
91-
if (!_var.IsNumeric()) {
94+
if (!_var.IsFloat()) {
9295
return error("Could not cast to double.");
9396
}
9497
return static_cast<T>(_var.AsDouble());
98+
9599
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
96-
if (!_var.IsNumeric()) {
100+
if (!_var.IsIntOrUint()) {
97101
return error("Could not cast to int.");
98102
}
99103
return static_cast<T>(_var.AsInt64());
104+
100105
} else {
101106
static_assert(rfl::always_false_v<T>, "Unsupported type.");
102107
}

include/rfl/json/Reader.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,26 +109,31 @@ struct Reader {
109109
return error("Could not cast to string.");
110110
}
111111
return std::string(r);
112+
112113
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
113114
if (!yyjson_is_bool(_var.val_)) {
114115
return error("Could not cast to boolean.");
115116
}
116117
return yyjson_get_bool(_var.val_);
118+
117119
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
118120
if (!yyjson_is_num(_var.val_)) {
119121
return error("Could not cast to double.");
120122
}
121123
return static_cast<T>(yyjson_get_num(_var.val_));
124+
122125
} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
123126
if (!yyjson_is_int(_var.val_)) {
124127
return error("Could not cast to int.");
125128
}
126129
return static_cast<T>(yyjson_get_uint(_var.val_));
130+
127131
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
128132
if (!yyjson_is_int(_var.val_)) {
129133
return error("Could not cast to int.");
130134
}
131135
return static_cast<T>(yyjson_get_sint(_var.val_));
136+
132137
} else {
133138
static_assert(rfl::always_false_v<T>, "Unsupported type.");
134139
}

include/rfl/msgpack/Reader.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ struct Reader {
6464
}
6565
const auto str = _var.via.str;
6666
return std::string(str.ptr, str.size);
67+
6768
} else if constexpr (std::is_same<std::remove_cvref_t<T>,
6869
rfl::Bytestring>()) {
6970
if (type != MSGPACK_OBJECT_BIN) {
@@ -72,11 +73,13 @@ struct Reader {
7273
const auto bin = _var.via.bin;
7374
const auto data = internal::ptr_cast<const std::byte*>(bin.ptr);
7475
return rfl::Bytestring(data, data + bin.size);
76+
7577
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
7678
if (type != MSGPACK_OBJECT_BOOLEAN) {
7779
return error("Could not cast to boolean.");
7880
}
7981
return _var.via.boolean;
82+
8083
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
8184
if (type == MSGPACK_OBJECT_FLOAT32 || type == MSGPACK_OBJECT_FLOAT64 ||
8285
type == MSGPACK_OBJECT_FLOAT) {
@@ -85,6 +88,7 @@ struct Reader {
8588
return error(
8689
"Could not cast to numeric value. The type must be float "
8790
"or double.");
91+
8892
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
8993
if (type == MSGPACK_OBJECT_POSITIVE_INTEGER) {
9094
return static_cast<T>(_var.via.u64);

include/rfl/toml/Reader.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,25 @@ struct Reader {
6060
return error("Could not cast to std::string!");
6161
}
6262
return _var->as_string();
63+
6364
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
6465
if (!_var->is_boolean()) {
6566
return error("Could not cast to bool!");
6667
}
6768
return _var->as_boolean();
69+
6870
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
6971
if (!_var->is_floating()) {
7072
return error("Could not cast to double!");
7173
}
7274
return static_cast<std::remove_cvref_t<T>>(_var->as_floating());
75+
7376
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
7477
if (!_var->is_integer()) {
7578
return error("Could not cast to int64_t!");
7679
}
7780
return static_cast<std::remove_cvref_t<T>>(_var->as_integer());
81+
7882
} else {
7983
static_assert(rfl::always_false_v<T>, "Unsupported type.");
8084
}

include/rfl/ubjson/Reader.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class Reader {
7171
return error("Could not cast to string.");
7272
}
7373
return _var.val_->as<std::string>();
74+
7475
} else if constexpr (std::is_same<std::remove_cvref_t<T>,
7576
rfl::Bytestring>()) {
7677
if (!_var.val_->is<std::vector<uint8_t>>()) {
@@ -79,25 +80,28 @@ class Reader {
7980
const auto vec = _var.val_->as<std::vector<uint8_t>>();
8081
const auto data = internal::ptr_cast<const std::byte*>(vec.data());
8182
return rfl::Bytestring(data, data + vec.size());
83+
8284
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
8385
if (!_var.val_->is_bool()) {
8486
return error("Could not cast to boolean.");
8587
}
8688
return _var.val_->as<bool>();
87-
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
88-
std::is_integral<std::remove_cvref_t<T>>()) {
89+
90+
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
8991
if (_var.val_->is_double()) {
9092
return static_cast<T>(_var.val_->as<double>());
9193
}
94+
return error("Could not cast to floating point value.");
95+
96+
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
9297
if (_var.val_->is_int64()) {
9398
return static_cast<T>(_var.val_->as<int64_t>());
9499
}
95100
if (_var.val_->is_uint64()) {
96101
return static_cast<T>(_var.val_->as<uint64_t>());
97102
}
98-
return error(
99-
"Could not cast to numeric value. The type must be integral, "
100-
"float or double.");
103+
return error("Could not cast to integer.");
104+
101105
} else {
102106
static_assert(rfl::always_false_v<T>, "Unsupported type.");
103107
}

include/rfl/xml/Reader.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ struct Reader {
8383

8484
if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
8585
return std::visit(get_value, _var.node_or_attribute_);
86+
8687
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
8788
return std::visit(get_value, _var.node_or_attribute_) == "true";
89+
8890
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
8991
const auto str = std::visit(get_value, _var.node_or_attribute_);
9092
try {
@@ -93,13 +95,15 @@ struct Reader {
9395
return error("Could not cast '" + std::string(str) +
9496
"' to floating point value.");
9597
}
98+
9699
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
97100
const auto str = std::visit(get_value, _var.node_or_attribute_);
98101
try {
99102
return static_cast<T>(std::stoi(str));
100103
} catch (std::exception& e) {
101104
return error("Could not cast '" + std::string(str) + "' to integer.");
102105
}
106+
103107
} else {
104108
static_assert(rfl::always_false_v<T>, "Unsupported type.");
105109
}

0 commit comments

Comments
 (0)