summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/escape.c28
-rw-r--r--src/basic/escape.h1
-rw-r--r--src/basic/hexdecoct.c3
-rw-r--r--src/basic/util.h10
4 files changed, 41 insertions, 1 deletions
diff --git a/src/basic/escape.c b/src/basic/escape.c
index 2e483880c8..01daf11ce7 100644
--- a/src/basic/escape.c
+++ b/src/basic/escape.c
@@ -413,6 +413,34 @@ char *xescape(const char *s, const char *bad) {
return r;
}
+char *octescape(const char *s, size_t len) {
+ char *r, *t;
+ const char *f;
+
+ /* Escapes all chars in bad, in addition to \ and " chars,
+ * in \nnn style escaping. */
+
+ r = new(char, len * 4 + 1);
+ if (!r)
+ return NULL;
+
+ for (f = s, t = r; f < s + len; f++) {
+
+ if (*f < ' ' || *f >= 127 || *f == '\\' || *f == '"') {
+ *(t++) = '\\';
+ *(t++) = '0' + (*f >> 6);
+ *(t++) = '0' + ((*f >> 3) & 8);
+ *(t++) = '0' + (*f & 8);
+ } else
+ *(t++) = *f;
+ }
+
+ *t = 0;
+
+ return r;
+
+}
+
static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
assert(bad);
diff --git a/src/basic/escape.h b/src/basic/escape.h
index 1b28bd10af..deaa4def28 100644
--- a/src/basic/escape.h
+++ b/src/basic/escape.h
@@ -48,6 +48,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
char *xescape(const char *s, const char *bad);
+char *octescape(const char *s, size_t len);
char *shell_escape(const char *s, const char *bad);
char *shell_maybe_quote(const char *s);
diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c
index 592df53cb5..d7ad8d41f2 100644
--- a/src/basic/hexdecoct.c
+++ b/src/basic/hexdecoct.c
@@ -25,6 +25,7 @@
#include "alloc-util.h"
#include "hexdecoct.h"
#include "macro.h"
+#include "util.h"
char octchar(int x) {
return '0' + (x & 7);
@@ -572,7 +573,7 @@ static int base64_append_width(char **prefix, int plen,
if (!t)
return -ENOMEM;
- memcpy(t + plen, sep, slen);
+ memcpy_safe(t + plen, sep, slen);
for (line = 0, s = t + plen + slen, avail = len; line < lines; line++) {
int act = MIN(width, avail);
diff --git a/src/basic/util.h b/src/basic/util.h
index 6f42c85a33..e095254b57 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -102,6 +102,16 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, comparison_
qsort(base, nmemb, size, compar);
}
+/**
+ * Normal memcpy requires src to be nonnull. We do nothing if n is 0.
+ */
+static inline void memcpy_safe(void *dst, const void *src, size_t n) {
+ if (n == 0)
+ return;
+ assert(src);
+ memcpy(dst, src, n);
+}
+
int on_ac_power(void);
#define memzero(x,l) (memset((x), 0, (l)))