Skip to content

Commit

Permalink
nall: always pass by reference to make_string()
Browse files Browse the repository at this point in the history
Many specializations of stringify store a reference to the wrapped
value. Therefore, passing arguments to make_string() by value can be
disastrous if the compiler does not perform copy elision and stringify
stores a reference to a variable that goes out of scope when
make_string() returns.

Cherry-picked from ares commit 3d826f5b266027529f0c12211c744a23bbe25a56.
  • Loading branch information
invertego authored and Screwtapello committed Sep 4, 2024
1 parent 4adbcdc commit ccc1a20
Showing 1 changed file with 3 additions and 41 deletions.
44 changes: 3 additions & 41 deletions nall/string/cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,16 +169,6 @@ template<uint Bits> struct stringify<Real<Bits>> {
//arrays

template<> struct stringify<vector<uint8_t>> {
stringify(vector<uint8_t> source) {
_text.resize(source.size());
memory::copy(_text.data(), source.data(), source.size());
}
auto data() const -> const char* { return _text.data(); }
auto size() const -> uint { return _text.size(); }
vector<char> _text;
};

template<> struct stringify<const vector<uint8_t>&> {
stringify(const vector<uint8_t>& source) {
_text.resize(source.size());
memory::copy(_text.data(), source.data(), source.size());
Expand All @@ -191,7 +181,7 @@ template<> struct stringify<const vector<uint8_t>&> {
//char arrays

template<> struct stringify<char*> {
stringify(char* source) : _data(source ? source : "") {}
stringify(const char* source) : _data(source ? source : "") {}
auto data() const -> const char* { return _data; }
auto size() const -> uint { return strlen(_data); }
const char* _data;
Expand All @@ -213,55 +203,27 @@ template<> struct stringify<string> {
const string& _text;
};

template<> struct stringify<const string&> {
stringify(const string& source) : _text(source) {}
auto data() const -> const char* { return _text.data(); }
auto size() const -> uint { return _text.size(); }
const string& _text;
};

template<> struct stringify<string_view> {
stringify(const string_view& source) : _view(source) {}
auto data() const -> const char* { return _view.data(); }
auto size() const -> uint { return _view.size(); }
const string_view& _view;
};

template<> struct stringify<const string_view&> {
stringify(const string_view& source) : _view(source) {}
auto data() const -> const char* { return _view.data(); }
auto size() const -> uint { return _view.size(); }
const string_view& _view;
};

template<> struct stringify<array_view<uint8_t>> {
stringify(const array_view<uint8_t>& source) : _view(source) {}
auto data() const -> const char* { return _view.data<const char>(); }
auto size() const -> uint { return _view.size(); }
const array_view<uint8_t>& _view;
};

template<> struct stringify<const array_view<uint8_t>&> {
stringify(const array_view<uint8_t>& source) : _view(source) {}
auto data() const -> const char* { return _view.data<const char>(); }
auto size() const -> uint { return _view.size(); }
const array_view<uint8_t>& _view;
};

template<> struct stringify<string_pascal> {
stringify(const string_pascal& source) : _text(source) {}
auto data() const -> const char* { return _text.data(); }
auto size() const -> uint { return _text.size(); }
const string_pascal& _text;
};

template<> struct stringify<const string_pascal&> {
stringify(const string_pascal& source) : _text(source) {}
auto data() const -> const char* { return _text.data(); }
auto size() const -> uint { return _text.size(); }
const string_pascal& _text;
};

//pointers

//note: T = char* is matched by stringify<string_view>
Expand All @@ -281,8 +243,8 @@ template<typename T> struct stringify<T*> {

//

template<typename T> auto make_string(T value) -> stringify<T> {
return stringify<T>(forward<T>(value));
template<typename T> auto make_string(const T& value) {
return stringify<std::decay_t<T>>(value);
}

}

0 comments on commit ccc1a20

Please sign in to comment.