From: Lennart Poettering Date: Mon, 25 Jul 2016 18:50:24 +0000 (+0200) Subject: sd-id128: be more liberal when reading files with 128bit IDs X-Git-Tag: v231~2^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=65548c58dddf721d03d8a5f5c96b196510f158fb;p=platform%2Fupstream%2Fsystemd.git sd-id128: be more liberal when reading files with 128bit IDs Accept both files with and without trailing newlines. Apparently some rkt releases generated them incorrectly, missing the trailing newlines, and we shouldn't break that. --- diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c index aaac838..c3f527d 100644 --- a/src/libsystemd/sd-id128/id128-util.c +++ b/src/libsystemd/sd-id128/id128-util.c @@ -100,33 +100,45 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) { assert(f < _ID128_FORMAT_MAX); /* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both - * followed by a newline and nothing else. */ + * optionally followed by a newline and nothing else. ID files should really be newline terminated, but if they + * aren't that's OK too, following the rule of "Be conservative in what you send, be liberal in what you + * accept". */ - l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 33 or 37 chars */ + l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 32/33 or 36/37 chars */ if (l < 0) return (int) l; if (l == 0) /* empty? */ return -ENOMEDIUM; - if (l == 33) { - if (f == ID128_UUID) - return -EINVAL; + switch (l) { + case 33: /* plain UUID with trailing newline */ if (buffer[32] != '\n') return -EINVAL; + /* fall through */ + case 32: /* plain UUID without trailing newline */ + if (f == ID128_UUID) + return -EINVAL; + buffer[32] = 0; + break; - } else if (l == 37) { - if (f == ID128_PLAIN) + case 37: /* RFC UUID with trailing newline */ + if (buffer[36] != '\n') return -EINVAL; - if (buffer[36] != '\n') + /* fall through */ + case 36: /* RFC UUID without trailing newline */ + if (f == ID128_PLAIN) return -EINVAL; buffer[36] = 0; - } else + break; + + default: return -EINVAL; + } return sd_id128_from_string(buffer, ret); } diff --git a/src/test/test-id128.c b/src/test/test-id128.c index 324c7a2..f01fbdd 100644 --- a/src/test/test-id128.c +++ b/src/test/test-id128.c @@ -23,10 +23,12 @@ #include "sd-id128.h" #include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "id128-util.h" #include "macro.h" #include "string-util.h" #include "util.h" -#include "id128-util.h" #define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10) #define STR_WALDI "0102030405060708090a0b0c0d0e0f10" @@ -36,6 +38,7 @@ int main(int argc, char *argv[]) { sd_id128_t id, id2; char t[33], q[37]; _cleanup_free_ char *b = NULL; + _cleanup_close_ int fd = -1; assert_se(sd_id128_randomize(&id) == 0); printf("random: %s\n", sd_id128_to_string(id, t)); @@ -86,5 +89,69 @@ int main(int argc, char *argv[]) { assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10")); assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10")); + fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC); + assert_se(fd >= 0); + + /* First, write as UUID */ + assert_se(sd_id128_randomize(&id) >= 0); + assert_se(id128_write_fd(fd, ID128_UUID, id, false) >= 0); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + + /* Second, write as plain */ + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(ftruncate(fd, 0) >= 0); + + assert_se(sd_id128_randomize(&id) >= 0); + assert_se(id128_write_fd(fd, ID128_PLAIN, id, false) >= 0); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + + /* Third, write plain without trailing newline */ + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(ftruncate(fd, 0) >= 0); + + assert_se(sd_id128_randomize(&id) >= 0); + assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + + /* Third, write UUID without trailing newline */ + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(ftruncate(fd, 0) >= 0); + + assert_se(sd_id128_randomize(&id) >= 0); + assert_se(write(fd, id128_to_uuid_string(id, t), 36) == 36); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL); + + assert_se(lseek(fd, 0, SEEK_SET) == 0); + assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0); + assert_se(sd_id128_equal(id, id2)); + return 0; }