summaryrefslogtreecommitdiff
path: root/include/rtl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2023-03-27 14:22:03 +0200
committerStephan Bergmann <sbergman@redhat.com>2023-03-27 15:18:44 +0000
commit58dd5870a77344754ea459d8423d1b3787a6a813 (patch)
treee2dedf1618ecb40d892d5fe57ff0a175fc9fb20d /include/rtl
parent4ca42f5d7c6b29814741f6df74dbc22ea45b47ca (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.hxx4
-rw-r--r--include/rtl/stringconcat.hxx20
-rw-r--r--include/rtl/ustring.hxx4
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: