summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrantisek Sumsal <frantisek@sumsal.cz>2021-03-05 14:19:21 +0100
committerGitHub <noreply@github.com>2021-03-05 14:19:21 +0100
commit3ee0cf339bf82f39eaf094ad5ac42b844a9879e1 (patch)
treebae403d6499c0a456f36bdab510d74ab60da5cb2 /src
parent275334c562907c174ec34a81a00e734e0b89ba36 (diff)
parent3509c7874bc15812f920eb988a5800473f9c905b (diff)
downloadsystemd-3ee0cf339bf82f39eaf094ad5ac42b844a9879e1.tar.gz
Merge pull request #18885 from yuwata/udev-fix-import-program-rhbz-1935062
udev: fix importing program result
Diffstat (limited to 'src')
-rw-r--r--src/basic/strv.c25
-rw-r--r--src/basic/strv.h16
-rw-r--r--src/test/test-device-nodes.c1
-rw-r--r--src/test/test-strv.c34
-rw-r--r--src/udev/udev-event.c8
-rw-r--r--src/udev/udev-rules.c7
6 files changed, 68 insertions, 23 deletions
diff --git a/src/basic/strv.c b/src/basic/strv.c
index 492dfe4002..765da04a7b 100644
--- a/src/basic/strv.c
+++ b/src/basic/strv.c
@@ -240,27 +240,28 @@ int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) {
return 0;
}
-char **strv_split_newlines(const char *s) {
- char **l;
+int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags) {
+ _cleanup_strv_free_ char **l = NULL;
size_t n;
+ int r;
assert(s);
- /* Special version of strv_split() that splits on newlines and
- * suppresses an empty string at the end */
+ /* Special version of strv_split_full() that splits on newlines and
+ * suppresses an empty string at the end. */
- l = strv_split(s, NEWLINE);
- if (!l)
- return NULL;
+ r = strv_split_full(&l, s, NEWLINE, flags);
+ if (r < 0)
+ return r;
n = strv_length(l);
- if (n <= 0)
- return l;
-
- if (isempty(l[n - 1]))
+ if (n > 0 && isempty(l[n - 1])) {
l[n - 1] = mfree(l[n - 1]);
+ n--;
+ }
- return l;
+ *ret = TAKE_PTR(l);
+ return n;
}
int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags) {
diff --git a/src/basic/strv.h b/src/basic/strv.h
index 6b3e8e7f86..911528fab4 100644
--- a/src/basic/strv.h
+++ b/src/basic/strv.h
@@ -73,15 +73,21 @@ static inline bool strv_isempty(char * const *l) {
return !l || !*l;
}
-char **strv_split_newlines(const char *s);
-
int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags);
static inline char **strv_split(const char *s, const char *separators) {
char **ret;
- int r;
- r = strv_split_full(&ret, s, separators, 0);
- if (r < 0)
+ if (strv_split_full(&ret, s, separators, 0) < 0)
+ return NULL;
+
+ return ret;
+}
+
+int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags);
+static inline char **strv_split_newlines(const char *s) {
+ char **ret;
+
+ if (strv_split_newlines_full(&ret, s, 0) < 0)
return NULL;
return ret;
diff --git a/src/test/test-device-nodes.c b/src/test/test-device-nodes.c
index 9efb3fe3b3..c914d78324 100644
--- a/src/test/test-device-nodes.c
+++ b/src/test/test-device-nodes.c
@@ -31,6 +31,7 @@ static void test_encode_devnode_name(void) {
assert_se(expect_encoded_as("s/ash/ng", "s\\x2fash\\x2fng"));
assert_se(expect_encoded_as("/", "\\x2f"));
assert_se(expect_encoded_as("!", "\\x21"));
+ assert_se(expect_encoded_as("QEMU ", "QEMU\\x20\\x20\\x20\\x20"));
}
int main(int argc, char *argv[]) {
diff --git a/src/test/test-strv.c b/src/test/test-strv.c
index 6b5005f9fc..162d8bed95 100644
--- a/src/test/test-strv.c
+++ b/src/test/test-strv.c
@@ -118,6 +118,20 @@ static const char* const input_table_one_empty[] = {
NULL,
};
+static const char* const input_table_unescape[] = {
+ "ID_VENDOR=QEMU",
+ "ID_VENDOR_ENC=QEMUx20x20x20x20",
+ "ID_MODEL_ENC=QEMUx20HARDDISKx20x20x20",
+ NULL,
+};
+
+static const char* const input_table_retain_escape[] = {
+ "ID_VENDOR=QEMU",
+ "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20",
+ "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20",
+ NULL,
+};
+
static void test_strv_find(void) {
log_info("/* %s */", __func__);
@@ -453,6 +467,25 @@ static void test_strv_split_newlines(void) {
assert_se(streq(*s, input_table_multiple[i++]));
}
+static void test_strv_split_newlines_full(void) {
+ const char str[] =
+ "ID_VENDOR=QEMU\n"
+ "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20\n"
+ "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20\n"
+ "\n\n\n";
+ _cleanup_strv_free_ char **l = NULL;
+
+ log_info("/* %s */", __func__);
+
+ assert_se(strv_split_newlines_full(&l, str, 0) == 3);
+ assert_se(strv_equal(l, (char**) input_table_unescape));
+
+ l = strv_free(l);
+
+ assert_se(strv_split_newlines_full(&l, str, EXTRACT_RETAIN_ESCAPE) == 3);
+ assert_se(strv_equal(l, (char**) input_table_retain_escape));
+}
+
static void test_strv_split_nulstr(void) {
_cleanup_strv_free_ char **l = NULL;
const char nulstr[] = "str0\0str1\0str2\0str3\0";
@@ -1031,6 +1064,7 @@ int main(int argc, char *argv[]) {
test_strv_split_full();
test_strv_split_colon_pairs();
test_strv_split_newlines();
+ test_strv_split_newlines_full();
test_strv_split_nulstr();
test_strv_parse_nulstr();
test_strv_overlap();
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 78a999d00a..d5d89d6802 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -573,9 +573,11 @@ static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userd
_cleanup_strv_free_ char **v = NULL;
char **q;
- v = strv_split_newlines(p);
- if (!v)
- log_oom_debug();
+ r = strv_split_newlines_full(&v, p, EXTRACT_RETAIN_ESCAPE);
+ if (r < 0)
+ log_device_debug(spawn->device,
+ "Failed to split output from '%s'(%s), ignoring: %m",
+ spawn->cmd, fd == spawn->fd_stdout ? "out" : "err");
STRV_FOREACH(q, v)
log_device_debug(spawn->device, "'%s'(%s) '%s'", spawn->cmd,
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 0f10116a99..57ede6a197 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -1746,9 +1746,10 @@ static int udev_rule_apply_token_to_event(
return token->op == OP_NOMATCH;
}
- lines = strv_split_newlines(result);
- if (!lines)
- return log_oom();
+ r = strv_split_newlines_full(&lines, result, EXTRACT_RETAIN_ESCAPE);
+ if (r < 0)
+ log_rule_warning_errno(dev, rules, r,
+ "Failed to extract lines from result of command \"%s\", ignoring: %m", buf);
STRV_FOREACH(line, lines) {
char *key, *value;