# HG changeset patch # User Rubidium # Date 2023-06-30 16:15:32 # Node ID ac6d05fea0a16fc5ec750fd06ef6831190b9f6e9 # Parent 68994e4ae3c4aa11d01b678bd8d7ae917dfe8076 Codechange: use std::string instead of a temporary buffer for iconv calls diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.cpp @@ -124,29 +124,30 @@ static const char *GetLocalCode() * Convert between locales, which from and which to is set in the calling * functions OTTD2FS() and FS2OTTD(). */ -static const char *convert_tofrom_fs(iconv_t convd, const char *name, char *outbuf, size_t outlen) +static std::string convert_tofrom_fs(iconv_t convd, const std::string &name) { /* There are different implementations of iconv. The older ones, * e.g. SUSv2, pass a const pointer, whereas the newer ones, e.g. * IEEE 1003.1 (2004), pass a non-const pointer. */ #ifdef HAVE_NON_CONST_ICONV - char *inbuf = const_cast(name); + char *inbuf = const_cast(name.data()); #else - const char *inbuf = name; + const char *inbuf = name.data(); #endif - size_t inlen = strlen(name); - char *buf = outbuf; + /* If the output is UTF-32, then 1 ASCII character becomes 4 bytes. */ + size_t inlen = name.size(); + std::string buf(inlen * 4, '\0'); - strecpy(outbuf, name, outbuf + outlen); - + size_t outlen = buf.size(); + char *outbuf = buf.data(); iconv(convd, nullptr, nullptr, nullptr, nullptr); if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) { Debug(misc, 0, "[iconv] error converting '{}'. Errno {}", name, errno); + return name; } - *outbuf = '\0'; - /* FIX: invalid characters will abort conversion, but they shouldn't occur? */ + buf.resize(outbuf - buf.data()); return buf; } @@ -158,8 +159,6 @@ static const char *convert_tofrom_fs(ico std::string OTTD2FS(const std::string &name) { static iconv_t convd = (iconv_t)(-1); - char buf[1024] = {}; - if (convd == (iconv_t)(-1)) { const char *env = GetLocalCode(); convd = iconv_open(env, INTERNALCODE); @@ -169,7 +168,7 @@ std::string OTTD2FS(const std::string &n } } - return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf)); + return convert_tofrom_fs(convd, name); } /** @@ -180,8 +179,6 @@ std::string OTTD2FS(const std::string &n std::string FS2OTTD(const std::string &name) { static iconv_t convd = (iconv_t)(-1); - char buf[1024] = {}; - if (convd == (iconv_t)(-1)) { const char *env = GetLocalCode(); convd = iconv_open(INTERNALCODE, env); @@ -191,7 +188,7 @@ std::string FS2OTTD(const std::string &n } } - return convert_tofrom_fs(convd, name.c_str(), buf, lengthof(buf)); + return convert_tofrom_fs(convd, name); } #endif /* WITH_ICONV */