Skip to content

Commit 5accae0

Browse files
committed
json_object_from_fd_ex: fail if file is too large
If the input file is too large to fit into a printbuf then return an error value instead of silently truncating the parsed content. This introduces errno handling into printbuf to distinguish between an input file being too large and running out of memory.
1 parent 79459b2 commit 5accae0

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

json_util.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,22 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
101101
if (!tok)
102102
{
103103
_json_c_set_last_err(
104-
"json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", depth,
105-
strerror(errno));
104+
"json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n",
105+
depth, strerror(errno));
106106
printbuf_free(pb);
107107
return NULL;
108108
}
109109

110110
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
111111
{
112-
printbuf_memappend(pb, buf, ret);
112+
if (printbuf_memappend(pb, buf, ret) < 0)
113+
{
114+
_json_c_set_last_err("json_object_from_fd_ex: error reading fd %d: %s\n",
115+
fd, strerror(errno));
116+
json_tokener_free(tok);
117+
printbuf_free(pb);
118+
return NULL;
119+
}
113120
}
114121
if (ret < 0)
115122
{

printbuf.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "config.h"
1717

18+
#include <errno.h>
1819
#include <limits.h>
1920
#include <stdio.h>
2021
#include <stdlib.h>
@@ -56,6 +57,8 @@ struct printbuf *printbuf_new(void)
5657
*
5758
* If the current size is large enough, nothing is changed.
5859
*
60+
* If extension failed, errno is set to indicate the error.
61+
*
5962
* Note: this does not check the available space! The caller
6063
* is responsible for performing those calculations.
6164
*/
@@ -68,7 +71,10 @@ static int printbuf_extend(struct printbuf *p, int min_size)
6871
return 0;
6972
/* Prevent signed integer overflows with large buffers. */
7073
if (min_size > INT_MAX - 8)
74+
{
75+
errno = EFBIG;
7176
return -1;
77+
}
7278
if (p->size > INT_MAX / 2)
7379
new_size = min_size + 8;
7480
else {
@@ -77,7 +83,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
7783
new_size = min_size + 8;
7884
}
7985
#ifdef PRINTBUF_DEBUG
80-
MC_DEBUG("printbuf_memappend: realloc "
86+
MC_DEBUG("printbuf_extend: realloc "
8187
"bpos=%d min_size=%d old_size=%d new_size=%d\n",
8288
p->bpos, min_size, p->size, new_size);
8389
#endif /* PRINTBUF_DEBUG */
@@ -92,7 +98,10 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
9298
{
9399
/* Prevent signed integer overflows with large buffers. */
94100
if (size < 0 || size > INT_MAX - p->bpos - 1)
101+
{
102+
errno = EFBIG;
95103
return -1;
104+
}
96105
if (p->size <= p->bpos + size + 1)
97106
{
98107
if (printbuf_extend(p, p->bpos + size + 1) < 0)
@@ -112,7 +121,10 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
112121
offset = pb->bpos;
113122
/* Prevent signed integer overflows with large buffers. */
114123
if (len < 0 || offset < -1 || len > INT_MAX - offset)
124+
{
125+
errno = EFBIG;
115126
return -1;
127+
}
116128
size_needed = offset + len;
117129
if (pb->size < size_needed)
118130
{

tests/test_util_file.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ OK: correctly unable to parse contents of valid_nested.json with low max depth:
44

55
OK: json_object_from_file(./not_present.json) correctly returned NULL: json_object_from_file: error opening file ./not_present.json: ERRNO=ENOENT
66

7-
OK: json_object_from_fd(closed_fd), expecting NULL, EBADF, got:NULL, json_object_from_fd: error reading fd 10: ERRNO=EBADF
7+
OK: json_object_from_fd(closed_fd), expecting NULL, EBADF, got:NULL, json_object_from_fd_ex: error reading fd 10: ERRNO=EBADF
88

99
OK: json_object_to_file(json.out, jso)=0
1010
file[json.out], size=336, contents={"foo":1234,"foo1":"abcdefghijklmnopqrstuvwxyz","foo2":"abcdefghijklmnopqrstuvwxyz","foo3":"abcdefghijklmnopqrstuvwxyz","foo4":"abcdefghijklmnopqrstuvwxyz","foo5":"abcdefghijklmnopqrstuvwxyz","foo6":"abcdefghijklmnopqrstuvwxyz","foo7":"abcdefghijklmnopqrstuvwxyz","foo8":"abcdefghijklmnopqrstuvwxyz","foo9":"abcdefghijklmnopqrstuvwxyz"}

0 commit comments

Comments
 (0)