chiark / gitweb /
string-util: rework memory_erase() to not use GCC optimize attribute (#3812)
[elogind.git] / src / basic / string-util.c
index 6f4593e6b41259e1070cb4627acfe04a75d514fa..5d4510e1b3bc457103da44e9128cc240588fdc53 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <errno.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "alloc-util.h"
 #include "gunicode.h"
+#include "macro.h"
 #include "string-util.h"
 #include "utf8.h"
 #include "util.h"
@@ -318,6 +324,14 @@ char ascii_tolower(char x) {
         return x;
 }
 
+char ascii_toupper(char x) {
+
+        if (x >= 'a' && x <= 'z')
+                return x - 'a' + 'A';
+
+        return x;
+}
+
 char *ascii_strlower(char *t) {
         char *p;
 
@@ -329,6 +343,17 @@ char *ascii_strlower(char *t) {
         return t;
 }
 
+char *ascii_strupper(char *t) {
+        char *p;
+
+        assert(t);
+
+        for (p = t; *p; p++)
+                *p = ascii_toupper(*p);
+
+        return t;
+}
+
 char *ascii_strlower_n(char *t, size_t n) {
         size_t i;
 
@@ -472,7 +497,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
         }
 
         if (k > x) /* last character was wide and went over quota */
-                x ++;
+                x++;
 
         for (j = s + old_length; k < new_length && j > i; ) {
                 char32_t c;
@@ -798,25 +823,20 @@ int free_and_strdup(char **p, const char *s) {
         return 1;
 }
 
-#pragma GCC push_options
-#pragma GCC optimize("O0")
+/*
+ * Pointer to memset is volatile so that compiler must de-reference
+ * the pointer and can't assume that it points to any function in
+ * particular (such as memset, which it then might further "optimize")
+ * This approach is inspired by openssl's crypto/mem_clr.c.
+ */
+typedef void *(*memset_t)(void *,int,size_t);
 
-void* memory_erase(void *p, size_t l) {
-        volatile uint8_t* x = (volatile uint8_t*) p;
-
-        /* This basically does what memset() does, but hopefully isn't
-         * optimized away by the compiler. One of those days, when
-         * glibc learns memset_s() we should replace this call by
-         * memset_s(), but until then this has to do. */
-
-        for (; l > 0; l--)
-                *(x++) = 'x';
+static volatile memset_t memset_func = memset;
 
-        return p;
+void* memory_erase(void *p, size_t l) {
+        return memset_func(p, 'x', l);
 }
 
-#pragma GCC pop_options
-
 char* string_erase(char *x) {
 
         if (!x)