diff options
author | Seth Moore <sethmo@google.com> | 2021-06-30 18:38:23 -0700 |
---|---|---|
committer | Seth Moore <sethmo@google.com> | 2021-06-30 18:38:23 -0700 |
commit | b0c9795e040ef73f9d2cf5b44a104dd99d531644 (patch) | |
tree | 225b39f6a07685ac03481890a6b618ee99b514d9 | |
parent | 7d548df91959ac4dc30c8c1c8dc3db12894e7229 (diff) | |
download | libcppbor-b0c9795e040ef73f9d2cf5b44a104dd99d531644.tar.gz |
Don't allow implicit conversion to Arrayandroid-s-beta-5android-s-beta-4android-s-beta-3android-s-beta-5android-s-beta-4
The variadic Array constructor would implicitly make an Array object
from a single input that is convertable to an Item. This leads to
surprising behaviors wherein Arrays could be created unintentionally.
Fix this by making the variadic constructor only work for more than
one argument. Add an additional, single-item constructor that is
explicit.
Bug: 191778240
Test: cppbor_host_test_external
Change-Id: Ifadc6d3137ee285a81076a4125b6053f1d7c21c4
-rw-r--r-- | include/cppbor/cppbor.h | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/include/cppbor/cppbor.h b/include/cppbor/cppbor.h index b78c41f..9bad233 100644 --- a/include/cppbor/cppbor.h +++ b/include/cppbor/cppbor.h @@ -598,6 +598,13 @@ class Array : public Item { Array(Args&&... args); /** + * The above variadic constructor is disabled if sizeof(Args) != 1, so special + * case an explicit Array constructor for creating an Array with one Item. + */ + template <typename T, typename Enable> + explicit Array(T&& v); + + /** * Append a single element to the Array, of any compatible type. */ template <typename T> @@ -1039,14 +1046,21 @@ inline void map_helper(Map& map, Key&& key, Value&& value, Rest&&... rest) { } // namespace details template <typename... Args, - /* Prevent use as copy ctor */ typename = std::enable_if_t< - (sizeof...(Args)) != 1 || - !(std::is_same_v<Array, std::remove_cv_t<std::remove_reference_t<Args>>> || ...)>> + /* Prevent implicit construction with a single argument. */ + typename = std::enable_if_t<(sizeof...(Args)) != 1>> Array::Array(Args&&... args) { mEntries.reserve(sizeof...(args)); (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...); } +template <typename T, + /* Prevent use as copy constructor. */ + typename = std::enable_if_t< + !std::is_same_v<Array, std::remove_cv_t<std::remove_reference_t<T>>>>> +Array::Array(T&& v) { + mEntries.push_back(details::makeItem(std::forward<T>(v))); +} + template <typename T> Array& Array::add(T&& v) & { mEntries.push_back(details::makeItem(std::forward<T>(v))); |