[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