diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2023-03-27 14:22:03 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2023-03-27 15:18:44 +0000 |
commit | 58dd5870a77344754ea459d8423d1b3787a6a813 (patch) | |
tree | e2dedf1618ecb40d892d5fe57ff0a175fc9fb20d /include/rtl | |
parent | 4ca42f5d7c6b29814741f6df74dbc22ea45b47ca (diff) |
Avoid dangling references to temporary O[U]StringConcatMarker instances
...which were created in O[U]String::Concat and bound to O[U]StringConcat::left.
Thanks to Mike Kaganski for finding this.
Change-Id: Id7838bc55eec7cba8860c2ec21a247bf4abd3c62
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149629
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'include/rtl')
-rw-r--r-- | include/rtl/string.hxx | 4 | ||||
-rw-r--r-- | include/rtl/stringconcat.hxx | 20 | ||||
-rw-r--r-- | include/rtl/ustring.hxx | 4 |
3 files changed, 17 insertions, 11 deletions
diff --git a/include/rtl/string.hxx b/include/rtl/string.hxx index 6af1a1a3b339..70829b43aae2 100644 --- a/include/rtl/string.hxx +++ b/include/rtl/string.hxx @@ -2229,14 +2229,14 @@ public: // would not compile): template<typename T> [[nodiscard]] static OStringConcat<OStringConcatMarker, T> - Concat(T const & value) { return OStringConcat<OStringConcatMarker, T>({}, value); } + Concat(T const & value) { return OStringConcat<OStringConcatMarker, T>(value); } // This overload is needed so that an argument of type 'char const[N]' ends up as // 'OStringConcat<rtl::OStringConcatMarker, char const[N]>' rather than as // 'OStringConcat<rtl::OStringConcatMarker, char[N]>': template<typename T, std::size_t N> [[nodiscard]] static OStringConcat<OStringConcatMarker, T[N]> - Concat(T (& value)[N]) { return OStringConcat<OStringConcatMarker, T[N]>({}, value); } + Concat(T (& value)[N]) { return OStringConcat<OStringConcatMarker, T[N]>(value); } #endif }; diff --git a/include/rtl/stringconcat.hxx b/include/rtl/stringconcat.hxx index 4d4eccd60ba4..c94f8b919e14 100644 --- a/include/rtl/stringconcat.hxx +++ b/include/rtl/stringconcat.hxx @@ -459,16 +459,22 @@ template<typename C> struct ToStringHelper<std::basic_string_view<C>> { // An internal marker class used by O(U)String::Concat: template<typename C> struct StringConcatMarker {}; -template<typename C> struct ToStringHelper<StringConcatMarker<C>> { - static constexpr std::size_t length(StringConcatMarker<C>) { return 0; } - - constexpr C * operator()(C * buffer, StringConcatMarker<C>) const SAL_RETURNS_NONNULL - { return buffer; } -}; - using OStringConcatMarker = StringConcatMarker<char>; using OUStringConcatMarker = StringConcatMarker<sal_Unicode>; +template<typename C> constexpr bool allowStringConcat<C, StringConcatMarker<C>> = true; + +template <typename C, typename T2, std::enable_if_t<allowStringConcat<C, T2>, int> Dummy> +struct StringConcat<C, StringConcatMarker<C>, T2, Dummy> +{ +public: + StringConcat( const T2& right_ ) : right( right_ ) {} + std::size_t length() const { return ToStringHelper< T2 >::length( right ); } + C* addData( C* buffer ) const SAL_RETURNS_NONNULL { return ToStringHelper< T2 >()( buffer, right ); } +private: + const T2& right; +}; + } // namespace #endif diff --git a/include/rtl/ustring.hxx b/include/rtl/ustring.hxx index 008f820bb3b1..c3966ac15cab 100644 --- a/include/rtl/ustring.hxx +++ b/include/rtl/ustring.hxx @@ -3313,14 +3313,14 @@ public: // would not compile): template<typename T> [[nodiscard]] static OUStringConcat<OUStringConcatMarker, T> - Concat(T const & value) { return OUStringConcat<OUStringConcatMarker, T>({}, value); } + Concat(T const & value) { return OUStringConcat<OUStringConcatMarker, T>(value); } // This overload is needed so that an argument of type 'char const[N]' ends up as // 'OUStringConcat<rtl::OUStringConcatMarker, char const[N]>' rather than as // 'OUStringConcat<rtl::OUStringConcatMarker, char[N]>': template<typename T, std::size_t N> [[nodiscard]] static OUStringConcat<OUStringConcatMarker, T[N]> - Concat(T (& value)[N]) { return OUStringConcat<OUStringConcatMarker, T[N]>({}, value); } + Concat(T (& value)[N]) { return OUStringConcat<OUStringConcatMarker, T[N]>(value); } #endif private: |