Skip to content

Commit 1f05cf0

Browse files
fix: memory leak
Fix a memory leak due to out of bounds access at _jsonb_escape() Closes #3 Co-authored-by: Aníbal Portero Hermida <[email protected]>
1 parent 9079145 commit 1f05cf0

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

json-build.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,10 @@ _jsonb_escape(
371371
}
372372
}
373373

374-
if (*pos + len + extra_bytes > bufsize) return JSONB_ERROR_NOMEM;
374+
if (*pos + len + extra_bytes > bufsize) {
375+
*buf = '\0';
376+
return JSONB_ERROR_NOMEM;
377+
}
375378

376379
if (esc_buf) {
377380
*pos += len + extra_bytes;
@@ -400,7 +403,7 @@ jsonb_key(jsonb *b, char buf[], size_t bufsize, const char key[], size_t len)
400403
case JSONB_OBJECT_KEY_OR_CLOSE: {
401404
enum jsonbcode ret;
402405
BUFFER_COPY_CHAR(b, '"', pos, buf, bufsize);
403-
ret = _jsonb_escape(&pos, buf + b->pos, bufsize, key, len);
406+
ret = _jsonb_escape(&pos, buf + b->pos, bufsize - b->pos, key, len);
404407
if (ret != JSONB_OK) return ret;
405408
BUFFER_COPY(b, "\":", 2, pos, buf, bufsize);
406409
STACK_HEAD(b, JSONB_OBJECT_VALUE);
@@ -551,7 +554,7 @@ jsonb_string(
551554
return JSONB_ERROR_INPUT;
552555
}
553556
BUFFER_COPY_CHAR(b, '"', pos, buf, bufsize);
554-
ret = _jsonb_escape(&pos, buf + b->pos, bufsize, str, len);
557+
ret = _jsonb_escape(&pos, buf + b->pos, bufsize - b->pos, str, len);
555558
if (ret != JSONB_OK) return ret;
556559
BUFFER_COPY_CHAR(b, '"', pos, buf, bufsize);
557560
STACK_HEAD(b, next_state);

test/test.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,27 @@ check_string_escaping(void)
228228
PASS();
229229
}
230230

231+
TEST
232+
check_string_escaping_bounds(void)
233+
{
234+
const char str[] = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
235+
char buf[(sizeof("{}") - 1)
236+
+ 4 * ((sizeof("\"\"") - 1) + (sizeof(str) - 1))];
237+
jsonb b;
238+
239+
jsonb_init(&b);
240+
jsonb_object(&b, buf, sizeof(buf));
241+
ASSERT_EQm(buf, JSONB_OK,
242+
jsonb_key(&b, buf, sizeof(buf), str, sizeof(str) - 1));
243+
ASSERT_EQm(buf, JSONB_OK,
244+
jsonb_string(&b, buf, sizeof(buf), str, sizeof(str) - 1));
245+
ASSERT_EQm(buf, JSONB_ERROR_NOMEM,
246+
jsonb_key(&b, buf, sizeof(buf), str, sizeof(str) - 1));
247+
fprintf(stderr, "%s", buf);
248+
249+
PASS();
250+
}
251+
231252
TEST
232253
check_string_streaming(void)
233254
{
@@ -307,6 +328,7 @@ check_string_streaming(void)
307328
SUITE(string)
308329
{
309330
RUN_TEST(check_string_escaping);
331+
RUN_TEST(check_string_escaping_bounds);
310332
RUN_TEST(check_string_streaming);
311333
}
312334

0 commit comments

Comments
 (0)