mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #14675 from yuwata/network-dhcp-accept-nul
network: accept NUL character in SendOption=
This commit is contained in:
commit
4523f1db0f
@ -102,7 +102,7 @@ char *cescape(const char *s) {
|
|||||||
return cescape_length(s, strlen(s));
|
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;
|
int r = 1;
|
||||||
|
|
||||||
assert(p);
|
assert(p);
|
||||||
@ -171,7 +171,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Don't allow NUL bytes */
|
/* Don't allow NUL bytes */
|
||||||
if (a == 0 && b == 0)
|
if (a == 0 && b == 0 && !accept_nul)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*ret = (a << 4U) | b;
|
*ret = (a << 4U) | b;
|
||||||
@ -199,7 +199,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
|
|||||||
c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
|
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 */
|
/* Don't allow 0 chars */
|
||||||
if (c == 0)
|
if (c == 0 && !accept_nul)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*ret = c;
|
*ret = c;
|
||||||
@ -227,7 +227,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
|
|||||||
((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
|
((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
|
||||||
|
|
||||||
/* Don't allow 0 chars */
|
/* Don't allow 0 chars */
|
||||||
if (c == 0)
|
if (c == 0 && !accept_nul)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Don't allow invalid code points */
|
/* Don't allow invalid code points */
|
||||||
@ -267,7 +267,7 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* don't allow NUL bytes */
|
/* don't allow NUL bytes */
|
||||||
if (a == 0 && b == 0 && c == 0)
|
if (a == 0 && b == 0 && c == 0 && !accept_nul)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Don't allow bytes above 255 */
|
/* Don't allow bytes above 255 */
|
||||||
@ -333,7 +333,7 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
|
|||||||
return -EINVAL;
|
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 (k < 0) {
|
||||||
if (flags & UNESCAPE_RELAX) {
|
if (flags & UNESCAPE_RELAX) {
|
||||||
/* Invalid escape code, let's take it literal then */
|
/* Invalid escape code, let's take it literal then */
|
||||||
@ -360,14 +360,6 @@ int cunescape_length_with_prefix(const char *s, size_t length, const char *prefi
|
|||||||
return t - r;
|
return t - r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
|
|
||||||
return cunescape_length_with_prefix(s, length, NULL, flags, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cunescape(const char *s, UnescapeFlags flags, char **ret) {
|
|
||||||
return cunescape_length(s, strlen(s), flags, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) {
|
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits) {
|
||||||
char *ans, *t, *prev, *prev2;
|
char *ans, *t, *prev, *prev2;
|
||||||
const char *f;
|
const char *f;
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
|
#define SHELL_NEED_ESCAPE_POSIX "\\\'"
|
||||||
|
|
||||||
typedef enum UnescapeFlags {
|
typedef enum UnescapeFlags {
|
||||||
UNESCAPE_RELAX = 1,
|
UNESCAPE_RELAX = 1 << 0,
|
||||||
|
UNESCAPE_ACCEPT_NUL = 1 << 1,
|
||||||
} UnescapeFlags;
|
} UnescapeFlags;
|
||||||
|
|
||||||
typedef enum EscapeStyle {
|
typedef enum EscapeStyle {
|
||||||
@ -41,10 +42,14 @@ char *cescape(const char *s);
|
|||||||
char *cescape_length(const char *s, size_t n);
|
char *cescape_length(const char *s, size_t n);
|
||||||
int cescape_char(char c, char *buf);
|
int cescape_char(char c, char *buf);
|
||||||
|
|
||||||
int cunescape(const char *s, UnescapeFlags flags, char **ret);
|
|
||||||
int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret);
|
|
||||||
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
|
int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret);
|
||||||
int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit);
|
static inline int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
|
||||||
|
return cunescape_length_with_prefix(s, length, NULL, flags, ret);
|
||||||
|
}
|
||||||
|
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, bool accept_nul);
|
||||||
|
|
||||||
char *xescape_full(const char *s, const char *bad, size_t console_width, bool eight_bits);
|
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) {
|
static inline char *xescape(const char *s, const char *bad) {
|
||||||
|
@ -90,7 +90,7 @@ int extract_first_word(const char **p, char **ret, const char *separators, Extra
|
|||||||
bool eight_bit = false;
|
bool eight_bit = false;
|
||||||
char32_t u;
|
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 (r < 0) {
|
||||||
if (flags & EXTRACT_CUNESCAPE_RELAX) {
|
if (flags & EXTRACT_CUNESCAPE_RELAX) {
|
||||||
s[sz++] = '\\';
|
s[sz++] = '\\';
|
||||||
|
@ -390,7 +390,7 @@ int config_parse_dhcp_send_option(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DHCP_OPTION_DATA_STRING:
|
case DHCP_OPTION_DATA_STRING:
|
||||||
sz = cunescape(p, 0, &q);
|
sz = cunescape(p, UNESCAPE_ACCEPT_NUL, &q);
|
||||||
if (sz < 0) {
|
if (sz < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, sz,
|
log_syntax(unit, LOG_ERR, filename, line, sz,
|
||||||
"Failed to decode DHCPv4 option data, ignoring assignment: %s", p);
|
"Failed to decode DHCPv4 option data, ignoring assignment: %s", p);
|
||||||
|
@ -96,6 +96,22 @@ static void test_cunescape(void) {
|
|||||||
|
|
||||||
assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
|
assert_se(cunescape("A=A\\\\x0aB", UNESCAPE_RELAX, &unescaped) >= 0);
|
||||||
assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
|
assert_se(streq_ptr(unescaped, "A=A\\x0aB"));
|
||||||
|
unescaped = mfree(unescaped);
|
||||||
|
|
||||||
|
assert_se(cunescape("\\x00\\x00\\x00", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
|
||||||
|
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
|
||||||
|
unescaped = mfree(unescaped);
|
||||||
|
|
||||||
|
assert_se(cunescape("\\u0000\\u0000\\u0000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
|
||||||
|
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
|
||||||
|
unescaped = mfree(unescaped);
|
||||||
|
|
||||||
|
assert_se(cunescape("\\U00000000\\U00000000\\U00000000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
|
||||||
|
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
|
||||||
|
unescaped = mfree(unescaped);
|
||||||
|
|
||||||
|
assert_se(cunescape("\\000\\000\\000", UNESCAPE_ACCEPT_NUL, &unescaped) == 3);
|
||||||
|
assert_se(memcmp(unescaped, "\0\0\0", 3) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
|
static void test_shell_escape_one(const char *s, const char *bad, const char *expected) {
|
||||||
|
Loading…
Reference in New Issue
Block a user