X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;ds=sidebyside;f=src%2Fbasic%2Fescape.c;h=d43bdaebfc9922e0294a00a8b8dc4e2e45b3193c;hb=d93247127eb2e073a6d3b5bcc67bcc4048d674fe;hp=9dbfa6d6e0f8c8143e6409fd45e2483ae9a1031e;hpb=0281ee40d079fb3206a6c9ae9ed52566f64e9803;p=elogind.git diff --git a/src/basic/escape.c b/src/basic/escape.c index 9dbfa6d6e..d43bdaebf 100644 --- a/src/basic/escape.c +++ b/src/basic/escape.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,12 +17,15 @@ along with systemd; If not, see . ***/ +#include +#include +#include + #include "alloc-util.h" #include "escape.h" #include "hexdecoct.h" -#include "string-util.h" +#include "macro.h" #include "utf8.h" -#include "util.h" size_t cescape_char(char c, char *buf) { char * buf_old = buf; @@ -116,7 +117,7 @@ char *cescape(const char *s) { return cescape_length(s, strlen(s)); } -int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit) { +int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) { int r = 1; assert(p); @@ -227,7 +228,7 @@ int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit) int a[8]; unsigned i; - uint32_t c; + char32_t c; if (length != (size_t) -1 && length < 9) return -EINVAL; @@ -264,7 +265,7 @@ int cunescape_one(const char *p, size_t length, uint32_t *ret, bool *eight_bit) case '7': { /* octal encoding */ int a, b, c; - uint32_t m; + char32_t m; if (length != (size_t) -1 && length < 3) return -EINVAL; @@ -324,15 +325,15 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi for (f = s, t = r + pl; f < s + length; f++) { size_t remaining; - uint32_t u; bool eight_bit = false; + char32_t u; int k; remaining = s + length - f; assert(remaining > 0); if (*f != '\\') { - /* A literal literal, copy verbatim */ + /* A literal, copy verbatim */ *(t++) = *f; continue; } @@ -412,10 +413,45 @@ char *xescape(const char *s, const char *bad) { return r; } -static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) { +#if 0 /// UNNEEDED by elogind +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, bool escape_tab_nl) { assert(bad); for (; *s; s++) { + if (escape_tab_nl && IN_SET(*s, '\n', '\t')) { + *(t++) = '\\'; + *(t++) = *s == '\n' ? 'n' : 't'; + continue; + } + if (*s == '\\' || strchr(bad, *s)) *(t++) = '\\'; @@ -432,20 +468,21 @@ char *shell_escape(const char *s, const char *bad) { if (!r) return NULL; - t = strcpy_backslash_escaped(r, s, bad); + t = strcpy_backslash_escaped(r, s, bad, false); *t = 0; return r; } -char *shell_maybe_quote(const char *s) { +char* shell_maybe_quote(const char *s, EscapeStyle style) { const char *p; char *r, *t; assert(s); - /* Encloses a string in double quotes if necessary to make it - * OK as shell string. */ + /* Encloses a string in quotes if necessary to make it OK as a shell + * string. Note that we treat benign UTF-8 characters as needing + * escaping too, but that should be OK. */ for (p = s; *p; p++) if (*p <= ' ' || @@ -456,18 +493,32 @@ char *shell_maybe_quote(const char *s) { if (!*p) return strdup(s); - r = new(char, 1+strlen(s)*2+1+1); + r = new(char, (style == ESCAPE_POSIX) + 1 + strlen(s)*2 + 1 + 1); if (!r) return NULL; t = r; - *(t++) = '"'; + if (style == ESCAPE_BACKSLASH) + *(t++) = '"'; + else if (style == ESCAPE_POSIX) { + *(t++) = '$'; + *(t++) = '\''; + } else + assert_not_reached("Bad EscapeStyle"); + t = mempcpy(t, s, p - s); - t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE); + if (style == ESCAPE_BACKSLASH) + t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE, false); + else + t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE_POSIX, true); - *(t++)= '"'; + if (style == ESCAPE_BACKSLASH) + *(t++) = '"'; + else + *(t++) = '\''; *t = 0; return r; } +#endif // 0