summaryrefslogtreecommitdiff
path: root/unotools/source
diff options
context:
space:
mode:
authorNoel Grandin <noelgrandin@gmail.com>2021-07-18 10:07:57 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-07-19 08:54:40 +0200
commit7712eb23bc97090fdd655a36dfca0019d43799e6 (patch)
treeedb6a035ecad3a05f15ac44caa81a517dae594f4 /unotools/source
parent4408001f5c0a76107d8fe01053a0e6348100a878 (diff)
tdf#143409: fix Translation is not applied in some UI
regression from commit 0771ac00acc8730f77db76b901724f1513a32723 Author: Noel Grandin <noel@peralex.com> Date: Tue Jun 15 21:12:25 2021 +0200 use string_view in the Translate API Because I mixed string_view with C-style null-terminated strings. We are using string_view.data() to pass stuff to boost, but of course, doing that loses the fact that the string data has associated length, as it finds the length by looking for a terminating NULL. Change-Id: Ia0eb7be5621506dfe0a40a21f360da1b446f5591 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119120 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'unotools/source')
-rw-r--r--unotools/source/i18n/resmgr.cxx43
1 files changed, 33 insertions, 10 deletions
diff --git a/unotools/source/i18n/resmgr.cxx b/unotools/source/i18n/resmgr.cxx
index cdca420e2636..d35282025c4e 100644
--- a/unotools/source/i18n/resmgr.cxx
+++ b/unotools/source/i18n/resmgr.cxx
@@ -48,6 +48,7 @@
#include <boost/locale.hpp>
#include <boost/locale/gnu_gettext.hpp>
+#include <array>
#include <unordered_map>
#include <memory>
@@ -199,27 +200,49 @@ namespace Translate
OUString get(std::string_view sContextAndId, const std::locale &loc)
{
- std::string_view sContext;
- std::string_view sId;
- const char *p = strchr(sContextAndId.data(), '\004');
- if (!p)
- sId = sContextAndId;
+ constexpr int BUFLEN = 128;
+ // this function is performance-sensitive, so we allocate string data on stack
+ std::array<char, BUFLEN> sStackBuffer;
+ std::unique_ptr<char[]> xHeapBuffer;
+ char* pBuffer;
+ if (sContextAndId.size() < BUFLEN - 1)
+ pBuffer = sStackBuffer.data();
else
{
- sContext = std::string_view(sContextAndId.data(), p - sContextAndId.data());
- sId = sContextAndId.substr(p - sContextAndId.data() + 1);
- assert(!strchr(sId.data(), '\004') && "should be using nget, not get");
+ xHeapBuffer = std::make_unique<char[]>(sContextAndId.size()+1);
+ pBuffer = xHeapBuffer.get();
+ }
+
+ const char* pContext;
+ const char* pId;
+ auto idx = sContextAndId.find('\004');
+ memcpy(pBuffer, sContextAndId.data(), sContextAndId.size());
+ if (idx == std::string_view::npos)
+ {
+ pBuffer[sContextAndId.size()] = 0;
+ // point pContext at the null byte so it is an empty string
+ pContext = pBuffer + sContextAndId.size();
+ pId = pBuffer;
+ }
+ else
+ {
+ // stick a null byte in the middle to split it into two null-terminated strings
+ pBuffer[idx] = 0;
+ pBuffer[sContextAndId.size()] = 0;
+ pContext = pBuffer;
+ pId = pBuffer + idx + 1;
+ assert(!strchr(pId, '\004') && "should be using nget, not get");
}
//if it's a key id locale, generate it here
if (std::use_facet<boost::locale::info>(loc).language() == "qtz")
{
OString sKeyId(genKeyId(OString(sContextAndId).replace('\004', '|')));
- return OUString::fromUtf8(sKeyId) + u"\u2016" + createFromUtf8(sId.data(), sId.size());
+ return OUString::fromUtf8(sKeyId) + u"\u2016" + createFromUtf8(pId, strlen(pId));
}
//otherwise translate it
- const std::string ret = boost::locale::pgettext(sContext.data(), sId.data(), loc);
+ const std::string ret = boost::locale::pgettext(pContext, pId, loc);
OUString result(ExpandVariables(createFromUtf8(ret.data(), ret.size())));
if (comphelper::LibreOfficeKit::isActive())