mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
buffer[32] = 0;
|
||||
|
||||
} else if (l == 37) {
|
||||
if (f == ID128_PLAIN)
|
||||
/* fall through */
|
||||
case 32: /* plain UUID without trailing newline */
|
||||
if (f == ID128_UUID)
|
||||
return -EINVAL;
|
||||
|
||||
buffer[32] = 0;
|
||||
break;
|
||||
|
||||
case 37: /* RFC UUID with trailing newline */
|
||||
if (buffer[36] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user