return cescape_length(s, strlen(s));
}
-int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit) {
+int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul) {
int r = 1;
assert(p);
return -EINVAL;
/* Don't allow NUL bytes */
- if (a == 0 && b == 0)
+ if (a == 0 && b == 0 && !accept_nul)
return -EINVAL;
*ret = (a << 4U) | b;
c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
/* Don't allow 0 chars */
- if (c == 0)
+ if (c == 0 && !accept_nul)
return -EINVAL;
*ret = c;
((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
/* Don't allow 0 chars */
- if (c == 0)
+ if (c == 0 && !accept_nul)
return -EINVAL;
/* Don't allow invalid code points */
return -EINVAL;
/* don't allow NUL bytes */
- if (a == 0 && b == 0 && c == 0)
+ if (a == 0 && b == 0 && c == 0 && !accept_nul)
return -EINVAL;
/* Don't allow bytes above 255 */
return -EINVAL;
}
- k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit);
+ k = cunescape_one(f + 1, remaining - 1, &u, &eight_bit, flags & UNESCAPE_ACCEPT_NUL);
if (k < 0) {
if (flags & UNESCAPE_RELAX) {
/* Invalid escape code, let's take it literal then */
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
typedef enum UnescapeFlags {
- UNESCAPE_RELAX = 1,
+ UNESCAPE_RELAX = 1 << 0,
+ UNESCAPE_ACCEPT_NUL = 1 << 1,
} UnescapeFlags;
typedef enum EscapeStyle {
ESCAPE_BACKSLASH = 1,
- ESCAPE_POSIX = 2,
+ ESCAPE_POSIX = 2,
} EscapeStyle;
char *cescape(const char *s);
static inline int cunescape(const char *s, UnescapeFlags flags, char **ret) {
return cunescape_length(s, strlen(s), flags, ret);
}
-int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
+int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit, bool accept_nul);
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits);
static inline char *xescape(const char *s, const char *bad) {
bool eight_bit = false;
char32_t u;
- r = cunescape_one(*p, (size_t) -1, &u, &eight_bit);
+ r = cunescape_one(*p, (size_t) -1, &u, &eight_bit, false);
if (r < 0) {
if (flags & EXTRACT_CUNESCAPE_RELAX) {
s[sz++] = '\\';