aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
authorAndreas Rammhold <andreas@rammhold.de>2021-07-30 20:08:54 +0200
committerAndreas Rammhold <andreas@rammhold.de>2021-07-30 21:07:32 +0200
commitb9c9c2576658706939d20b1861309fefa7f20889 (patch)
tree607a499cf6bc1c1f78f5e964afce8d15cfbd3a33 /src/libutil/util.cc
parent2b67cb7b8c8ac7953f7e341d760bdb3c021fe765 (diff)
libutil: initialize the base64 decode array only once
Previously, despite having a boolean that tracked initialization, the decode characters have been "calculated" every single time a base64 string was being decoded. With this change we only initialize the decode array once in a thread-safe manner.
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc22
1 files changed, 10 insertions, 12 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index d876315c8..d1270cd31 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -6,14 +6,15 @@
#include <cctype>
#include <cerrno>
+#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
-#include <climits>
+#include <future>
#include <iostream>
+#include <mutex>
#include <sstream>
#include <thread>
-#include <future>
#include <fcntl.h>
#include <grp.h>
@@ -1447,7 +1448,7 @@ std::string filterANSIEscapes(const std::string & s, bool filterAll, unsigned in
static char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
+static std::array<char, 256> base64DecodeChars;
string base64Encode(std::string_view s)
{
@@ -1472,15 +1473,12 @@ string base64Encode(std::string_view s)
string base64Decode(std::string_view s)
{
- bool init = false;
- char decode[256];
- if (!init) {
- // FIXME: not thread-safe.
- memset(decode, -1, sizeof(decode));
+ static std::once_flag flag;
+ std::call_once(flag, [](){
+ base64DecodeChars = { (char)-1 };
for (int i = 0; i < 64; i++)
- decode[(int) base64Chars[i]] = i;
- init = true;
- }
+ base64DecodeChars[(int) base64Chars[i]] = i;
+ });
string res;
unsigned int d = 0, bits = 0;
@@ -1489,7 +1487,7 @@ string base64Decode(std::string_view s)
if (c == '=') break;
if (c == '\n') continue;
- char digit = decode[(unsigned char) c];
+ char digit = base64DecodeChars[(unsigned char) c];
if (digit == -1)
throw Error("invalid character in Base64 string: '%c'", c);