Skip to content

Commit c8498fb

Browse files
committed
fix Properties out-of-bounds check
+testcase
1 parent b81e576 commit c8498fb

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

include/mitsuba/core/properties.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,22 @@ class MI_EXPORT_LIB Properties {
181181

182182
// Perform a range check just in case
183183
if constexpr (std::is_integral_v<T2> && !std::is_same_v<T2, bool>) {
184-
constexpr T2 min = (T2) std::numeric_limits<T>::min(),
185-
max = (T2) std::numeric_limits<T>::max();
186-
187-
if (value < min || value > max)
184+
constexpr T min_t = std::numeric_limits<T>::min(),
185+
max_t = std::numeric_limits<T>::max();
186+
bool out_of_bounds = false;
187+
188+
if constexpr (std::is_unsigned_v<T>) {
189+
if constexpr (max_t <= (T) std::numeric_limits<T2>::max())
190+
out_of_bounds = value > (T2) max_t;
191+
if (value < 0)
192+
out_of_bounds = true;
193+
} else {
194+
out_of_bounds = value < (T2) min_t || value > (T2) max_t;
195+
}
196+
197+
if (out_of_bounds)
188198
Throw("Property \"%s\": value %lld is out of bounds, must be "
189-
"in the range [%lld, %lld]", name, value, min, max);
199+
"in the range [%lld, %lld]", name, value, min_t, max_t);
190200
}
191201

192202
if constexpr (std::is_same_v<T2, ref<Object>>) {
@@ -243,12 +253,23 @@ class MI_EXPORT_LIB Properties {
243253

244254
// Perform a range check just in case
245255
if constexpr (std::is_integral_v<T2> && !std::is_same_v<T2, bool>) {
246-
constexpr T2 min = (T2) std::numeric_limits<T>::min(),
247-
max = (T2) std::numeric_limits<T>::max();
256+
constexpr T min_t = std::numeric_limits<T>::min();
257+
constexpr T max_t = std::numeric_limits<T>::max();
258+
259+
bool out_of_bounds = false;
260+
261+
if constexpr (std::is_unsigned_v<T>) {
262+
if constexpr (max_t <= (T) std::numeric_limits<T2>::max())
263+
out_of_bounds = value > (T2) max_t;
264+
if (value < 0)
265+
out_of_bounds = true;
266+
} else {
267+
out_of_bounds = value < (T2) min_t || value > (T2) max_t;
268+
}
248269

249-
if (value < min || value > max)
270+
if (out_of_bounds)
250271
Throw("Property \"%s\": value %lld is out of bounds, must be "
251-
"in the range [%lld, %lld]", name, value, min, max);
272+
"in the range [%lld, %lld]", name, value, (T2) min_t, (T2) max_t);
252273
}
253274

254275
if constexpr (std::is_same_v<T2, ref<Object>>) {

src/core/tests/test_properties.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,7 @@ def test17_dictionary_like_interface(variant_scalar_rgb):
355355
assert 'remove_property() is deprecated' in str(w[2].message)
356356

357357

358+
def test18_range(variant_scalar_rgb):
359+
with pytest.raises(RuntimeError, match=r'Property "bsdf_samples": value -3 is out of bounds, must be in the range \[0, -1\]'):
360+
mi.load_dict({'type': 'direct', 'bsdf_samples': -3})
361+
mi.load_dict({'type': 'direct', 'bsdf_samples': 10})

0 commit comments

Comments
 (0)