]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-event: use in-place whitespace replacement 5168/head
authorDan Streetman <ddstreet@ieee.org>
Thu, 26 Jan 2017 19:18:10 +0000 (14:18 -0500)
committerDan Streetman <ddstreet@ieee.org>
Fri, 27 Jan 2017 12:58:00 +0000 (07:58 -0500)
Instead of using a temp buffer to replace whitespace in variable
substitutions, just allow util_replace_whitespace to replace in-place.
Add a comment to util_replace_whitespace indicating it is used to replace
in-place, to prevent accidental future breakage.

src/libudev/libudev-util.c
src/udev/udev-event.c

index a9819b9db30e0b0a2a4ca1d138ffe5b0ec00b9b0..1d73d8f09061ad852fc66cb4011b25f5fc9d3984 100644 (file)
@@ -161,6 +161,20 @@ void util_remove_trailing_chars(char *path, char c)
                 path[--len] = '\0';
 }
 
+/*
+ * Copy from 'str' to 'to', while removing all leading and trailing whitespace,
+ * and replacing each run of consecutive whitespace with a single underscore.
+ * The chars from 'str' are copied up to the \0 at the end of the string, or
+ * at most 'len' chars.  This appends \0 to 'to', at the end of the copied
+ * characters.
+ *
+ * If 'len' chars are copied into 'to', the final \0 is placed at len+1
+ * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1
+ * chars available.
+ *
+ * Note this may be called with 'str' == 'to', i.e. to replace whitespace
+ * in-place in a buffer.  This function can handle that situation.
+ */
 int util_replace_whitespace(const char *str, char *to, size_t len)
 {
         size_t i, j;
index 3cb2673291856574c44ffa80c1dfbc9716cde101..3f9c3ed0cfbfc7e4a4bc7c13a3a19a3eed614db0 100644 (file)
@@ -95,8 +95,8 @@ enum subst_type {
 
 static size_t subst_format_var(struct udev_event *event, struct udev_device *dev,
                                enum subst_type type, char *attr,
-                               char **dest, size_t l) {
-        char *s = *dest;
+                               char *dest, size_t l) {
+        char *s = dest;
 
         switch (type) {
         case SUBST_DEVPATH:
@@ -279,9 +279,7 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev
                 break;
         }
 
-        *dest = s;
-
-        return l;
+        return s - dest;
 }
 
 size_t udev_event_apply_format(struct udev_event *event,
@@ -324,10 +322,9 @@ size_t udev_event_apply_format(struct udev_event *event,
 
         for (;;) {
                 enum subst_type type = SUBST_UNKNOWN;
-                char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE];
-                char *attr = NULL, *_s;
-                size_t _l;
-                bool replws = replace_whitespace;
+                char attrbuf[UTIL_PATH_SIZE];
+                char *attr = NULL;
+                size_t subst_len;
 
                 while (from[0] != '\0') {
                         if (from[0] == '$') {
@@ -396,34 +393,17 @@ subst:
                         attr = NULL;
                 }
 
-                /* result subst handles space as field separator */
-                if (type == SUBST_RESULT)
-                        replws = false;
-
-                if (replws) {
-                        /* store dest string ptr and remaining len */
-                        _s = s;
-                        _l = l;
-                        /* temporarily use sbuf */
-                        s = sbuf;
-                        l = UTIL_PATH_SIZE;
-                }
-
-                l = subst_format_var(event, dev, type, attr, &s, l);
-
-                /* replace whitespace in sbuf and copy to dest */
-                if (replws) {
-                        size_t tmplen = UTIL_PATH_SIZE - l;
+                subst_len = subst_format_var(event, dev, type, attr, s, l);
 
-                        /* restore s and l to dest string values */
-                        s = _s;
-                        l = _l;
+                /* SUBST_RESULT handles spaces itself */
+                if (replace_whitespace && type != SUBST_RESULT)
+                        /* util_replace_whitespace can replace in-place,
+                         * and does nothing if subst_len == 0
+                         */
+                        subst_len = util_replace_whitespace(s, s, subst_len);
 
-                        /* copy ws-replaced value to s */
-                        tmplen = util_replace_whitespace(sbuf, s, MIN(tmplen, l));
-                        l -= tmplen;
-                        s += tmplen;
-                }
+                s += subst_len;
+                l -= subst_len;
         }
 
 out: