From 21c9b0e6b039e9765eb414c406c2b86e8cea6850 Mon Sep 17 00:00:00 2001
From: komels <komels@yandex-team.ru>
Date: Thu, 14 Apr 2022 13:10:53 +0300
Subject: Final part on compatibility layer: LOGBROKER-7215

ref:777c67aadbf705d19034a09a792b2df61ba53697
---
 .../string_utils/secret_string/secret_string.cpp   | 68 ++++++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 library/cpp/string_utils/secret_string/secret_string.cpp

(limited to 'library/cpp/string_utils/secret_string/secret_string.cpp')

diff --git a/library/cpp/string_utils/secret_string/secret_string.cpp b/library/cpp/string_utils/secret_string/secret_string.cpp
new file mode 100644
index 0000000000..3b68d3cd27
--- /dev/null
+++ b/library/cpp/string_utils/secret_string/secret_string.cpp
@@ -0,0 +1,68 @@
+#include "secret_string.h"
+
+#include <util/system/madvise.h>
+
+namespace NSecretString {
+    TSecretString::TSecretString(TStringBuf value) {
+        Init(value);
+    }
+
+    TSecretString::~TSecretString() {
+        try {
+            Clear();
+        } catch (...) {
+        }
+    }
+
+    TSecretString& TSecretString::operator=(const TSecretString& o) {
+        if (&o == this) {
+            return *this;
+        }
+
+        Init(o.Value_);
+
+        return *this;
+    }
+
+    /**
+     * It is not honest "move". Actually it is copy-assignment with cleaning of other instance.
+     * This way allowes to avoid side effects of string optimizations:
+     *   Copy-On-Write or Short-String-Optimization
+     */
+    TSecretString& TSecretString::operator=(TSecretString&& o) {
+        if (&o == this) {
+            return *this;
+        }
+
+        Init(o.Value_);
+        o.Clear();
+
+        return *this;
+    }
+
+    TSecretString& TSecretString::operator=(const TStringBuf o) {
+        Init(o);
+
+        return *this;
+    }
+
+    void TSecretString::Init(TStringBuf value) {
+        Clear();
+        if (value.empty()) {
+            return;
+        }
+
+        Value_ = value;
+        MadviseExcludeFromCoreDump(Value_);
+    }
+
+    void TSecretString::Clear() {
+        if (Value_.empty()) {
+            return;
+        }
+
+        SecureZero((void*)Value_.data(), Value_.size());
+        MadviseIncludeIntoCoreDump(Value_);
+        Value_.clear();
+    }
+}
-- 
cgit v1.2.3