diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2020-10-30 01:52:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-30 01:52:45 +0100 |
commit | 819a555bc5cccd6b4e8b53b7b5036744a94142a7 (patch) | |
tree | fb7b7a18837a18934c2425be6be0680a4acbc2dc /src/shared/udev-util.c | |
parent | Merge pull request #17444 from BtbN/fix_ib_dhcp4 (diff) | |
parent | document udev escaped string in udev(7) (diff) | |
download | systemd-819a555bc5cccd6b4e8b53b7b5036744a94142a7.tar.xz systemd-819a555bc5cccd6b4e8b53b7b5036744a94142a7.zip |
Merge pull request #17399 from afq984/udev-escaped-string
Allow escaped string in udev rules
Diffstat (limited to 'src/shared/udev-util.c')
-rw-r--r-- | src/shared/udev-util.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 33272de4bc..7bb9f40a75 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -6,13 +6,16 @@ #include "alloc-util.h" #include "device-util.h" #include "env-file.h" +#include "escape.h" #include "log.h" +#include "macro.h" #include "parse-util.h" #include "path-util.h" #include "signal-util.h" #include "string-table.h" #include "string-util.h" #include "udev-util.h" +#include "utf8.h" static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = { [RESOLVE_NAME_NEVER] = "never", @@ -320,3 +323,49 @@ bool device_for_action(sd_device *dev, DeviceAction action) { return a == action; } + +int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) { + char *i, *j; + int r; + bool is_escaped; + + /* value must be double quotated */ + is_escaped = str[0] == 'e'; + str += is_escaped; + if (str[0] != '"') + return -EINVAL; + str++; + + if (!is_escaped) { + /* unescape double quotation '\"'->'"' */ + for (i = j = str; *i != '"'; i++, j++) { + if (*i == '\0') + return -EINVAL; + if (i[0] == '\\' && i[1] == '"') + i++; + *j = *i; + } + j[0] = '\0'; + } else { + _cleanup_free_ char *unescaped = NULL; + + /* find the end position of value */ + for (i = str; *i != '"'; i++) { + if (i[0] == '\\') + i++; + if (*i == '\0') + return -EINVAL; + } + i[0] = '\0'; + + r = cunescape_length(str, i - str, 0, &unescaped); + if (r < 0) + return r; + assert(r <= i - str); + memcpy(str, unescaped, r + 1); + } + + *ret_value = str; + *ret_endpos = i + 1; + return 0; +} |