112 lines
3.5 KiB
Diff
112 lines
3.5 KiB
Diff
From 5accae04bbc727fd447c2db4c1c541a4142bd4a0 Mon Sep 17 00:00:00 2001
|
|
From: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
Date: Sun, 20 Mar 2022 13:17:37 +0100
|
|
Subject: [PATCH] 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.
|
|
|
|
Conflict:tests/test_util_file.expected,0.16 version has merge.
|
|
Reference:https://github.com/json-c/json-c/commit/5accae04bbc727fd447c2db4c1c541a4142bd4a0
|
|
---
|
|
json_util.c | 13 ++++++++++---
|
|
printbuf.c | 14 +++++++++++++-
|
|
2 files changed, 23 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/json_util.c b/json_util.c
|
|
index 3e6a6c681b..e1c05c5cfd 100644
|
|
--- a/json_util.c
|
|
+++ b/json_util.c
|
|
@@ -101,15 +101,22 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
|
|
if (!tok)
|
|
{
|
|
_json_c_set_last_err(
|
|
- "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", depth,
|
|
- strerror(errno));
|
|
+ "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n",
|
|
+ depth, strerror(errno));
|
|
printbuf_free(pb);
|
|
return NULL;
|
|
}
|
|
|
|
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
|
|
{
|
|
- printbuf_memappend(pb, buf, ret);
|
|
+ if (printbuf_memappend(pb, buf, ret) < 0)
|
|
+ {
|
|
+ _json_c_set_last_err("json_object_from_fd_ex: error reading fd %d: %s\n",
|
|
+ fd, strerror(errno));
|
|
+ json_tokener_free(tok);
|
|
+ printbuf_free(pb);
|
|
+ return NULL;
|
|
+ }
|
|
}
|
|
if (ret < 0)
|
|
{
|
|
diff --git a/printbuf.c b/printbuf.c
|
|
index a08f7b1582..12d3b3319d 100644
|
|
--- a/printbuf.c
|
|
+++ b/printbuf.c
|
|
@@ -15,6 +15,7 @@
|
|
|
|
#include "config.h"
|
|
|
|
+#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
@@ -56,6 +57,8 @@ struct printbuf *printbuf_new(void)
|
|
*
|
|
* If the current size is large enough, nothing is changed.
|
|
*
|
|
+ * If extension failed, errno is set to indicate the error.
|
|
+ *
|
|
* Note: this does not check the available space! The caller
|
|
* is responsible for performing those calculations.
|
|
*/
|
|
@@ -68,7 +71,10 @@ static int printbuf_extend(struct printbuf *p, int min_size)
|
|
return 0;
|
|
/* Prevent signed integer overflows with large buffers. */
|
|
if (min_size > INT_MAX - 8)
|
|
+ {
|
|
+ errno = EFBIG;
|
|
return -1;
|
|
+ }
|
|
if (p->size > INT_MAX / 2)
|
|
new_size = min_size + 8;
|
|
else {
|
|
@@ -77,7 +83,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
|
|
new_size = min_size + 8;
|
|
}
|
|
#ifdef PRINTBUF_DEBUG
|
|
- MC_DEBUG("printbuf_memappend: realloc "
|
|
+ MC_DEBUG("printbuf_extend: realloc "
|
|
"bpos=%d min_size=%d old_size=%d new_size=%d\n",
|
|
p->bpos, min_size, p->size, new_size);
|
|
#endif /* PRINTBUF_DEBUG */
|
|
@@ -92,7 +98,10 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
|
|
{
|
|
/* Prevent signed integer overflows with large buffers. */
|
|
if (size < 0 || size > INT_MAX - p->bpos - 1)
|
|
+ {
|
|
+ errno = EFBIG;
|
|
return -1;
|
|
+ }
|
|
if (p->size <= p->bpos + size + 1)
|
|
{
|
|
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)
|
|
offset = pb->bpos;
|
|
/* Prevent signed integer overflows with large buffers. */
|
|
if (len < 0 || offset < -1 || len > INT_MAX - offset)
|
|
+ {
|
|
+ errno = EFBIG;
|
|
return -1;
|
|
+ }
|
|
size_needed = offset + len;
|
|
if (pb->size < size_needed)
|
|
{
|