mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
fileio: make read_full_file_full() usable with size and READ_FULL_FILE_UNBASE64
When READ_FULL_FILE_UNBASE64 (or READ_FULL_FILE_UNHEX) is specified, setting size argument by caller is difficult, as it is hard to estimate the encoded length. This makes when size is specified with decoding option, let's read file more, and check decoded size later with the specified size.
This commit is contained in:
parent
b503c76689
commit
7e2a5fbd85
@ -32,6 +32,8 @@
|
||||
|
||||
/* The maximum size of the file we'll read in one go in read_full_file() (64M). */
|
||||
#define READ_FULL_BYTES_MAX (64U*1024U*1024U - 1U)
|
||||
/* Used when a size is specified for read_full_file() with READ_FULL_FILE_UNBASE64 or _UNHEX */
|
||||
#define READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY 3
|
||||
|
||||
/* The maximum size of virtual files (i.e. procfs, sysfs, and other virtual "API" files) we'll read in one go
|
||||
* in read_virtual_file(). Note that this limit is different (and much lower) than the READ_FULL_BYTES_MAX
|
||||
@ -572,7 +574,7 @@ int read_full_stream_full(
|
||||
size_t *ret_size) {
|
||||
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
size_t n, n_next = 0, l;
|
||||
size_t n, n_next = 0, l, expected_decoded_size = size;
|
||||
int fd, r;
|
||||
|
||||
assert(f);
|
||||
@ -583,6 +585,13 @@ int read_full_stream_full(
|
||||
if (offset != UINT64_MAX && offset > LONG_MAX) /* fseek() can only deal with "long" offsets */
|
||||
return -ERANGE;
|
||||
|
||||
if ((flags & (READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)) != 0) {
|
||||
if (size <= SIZE_MAX / READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY)
|
||||
size *= READ_FULL_FILE_ENCODED_STRING_AMPLIFICATION_BOUNDARY;
|
||||
else
|
||||
size = SIZE_MAX;
|
||||
}
|
||||
|
||||
fd = fileno(f);
|
||||
if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see
|
||||
* fmemopen()), let's optimize our buffering */
|
||||
@ -707,6 +716,11 @@ int read_full_stream_full(
|
||||
explicit_bzero_safe(buf, n);
|
||||
free_and_replace(buf, decoded);
|
||||
n = l = decoded_size;
|
||||
|
||||
if (FLAGS_SET(flags, READ_FULL_FILE_FAIL_WHEN_LARGER) && l > expected_decoded_size) {
|
||||
r = -E2BIG;
|
||||
goto finalize;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret_size) {
|
||||
|
Loading…
Reference in New Issue
Block a user