[LTP] [PATCH 11/15] ujson: reader: Support files with zero lseek size
Andrea Cervesato
andrea.cervesato@suse.de
Mon Oct 5 15:25:39 CEST 2026
From: Andrea Cervesato <andrea.cervesato@suse.com>
Files in pseudo-filesystems like /proc/sys report a size of 0 with
lseek(), causing ujson_reader_load() to allocate a 1-byte buffer and
skip the read loop entirely. seq_file based files such as
/proc/self/status do not support SEEK_END at all, making the load fail.
Allocate an initial capacity when the size is unknown and grow the
buffer with realloc() dynamically until EOF.
Fixes: c50a0e0751c8 ("libs: Vendor ujson library")
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
libs/ujson/ujson_reader.c | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/libs/ujson/ujson_reader.c b/libs/ujson/ujson_reader.c
index f4335407a..dd1d96d5f 100644
--- a/libs/ujson/ujson_reader.c
+++ b/libs/ujson/ujson_reader.c
@@ -1011,23 +1011,23 @@ ujson_reader *ujson_reader_load(const char *path)
int fd = open(path, O_RDONLY);
ujson_reader *ret;
ssize_t res;
- off_t len, off = 0;
+ off_t len;
+ size_t off = 0, capacity;
if (fd < 0)
return NULL;
+ /* Some pseudo-files (e.g. seq_file in /proc) do not support SEEK_END */
len = lseek(fd, 0, SEEK_END);
- if (len == (off_t)-1) {
- fprintf(stderr, "lseek() failed\n");
- goto err0;
- }
- if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ if (len > 0 && lseek(fd, 0, SEEK_SET) == (off_t)-1) {
fprintf(stderr, "lseek() failed\n");
goto err0;
}
- ret = malloc(sizeof(ujson_reader) + len + 1);
+ capacity = len > 0 ? (size_t)len + 1 : 4096;
+
+ ret = malloc(sizeof(ujson_reader) + capacity + 1);
if (!ret) {
fprintf(stderr, "malloc() failed\n");
goto err0;
@@ -1035,15 +1035,24 @@ ujson_reader *ujson_reader_load(const char *path)
memset(ret, 0, sizeof(*ret));
- ret->buf[len] = 0;
- ret->len = len;
ret->max_depth = UJSON_RECURSION_MAX;
- ret->json = ret->buf;
ret->err_print = UJSON_ERR_PRINT;
ret->err_print_priv = UJSON_ERR_PRINT_PRIV;
- while (off < len) {
- res = read(fd, ret->buf + off, len - off);
+ for (;;) {
+ if (off >= capacity) {
+ ujson_reader *new_ret;
+
+ capacity *= 2;
+ new_ret = realloc(ret, sizeof(ujson_reader) + capacity + 1);
+ if (!new_ret) {
+ fprintf(stderr, "realloc() failed\n");
+ goto err1;
+ }
+ ret = new_ret;
+ }
+
+ res = read(fd, ret->buf + off, capacity - off);
if (res < 0) {
fprintf(stderr, "read() failed\n");
goto err1;
@@ -1057,6 +1066,7 @@ ujson_reader *ujson_reader_load(const char *path)
ret->buf[off] = 0;
ret->len = off;
+ ret->json = ret->buf;
close(fd);
--
2.51.0
More information about the ltp
mailing list