Comments (5)
Where does it fail? Do you have a patch?
from json-c.
I don't have a patch, but you can find where it happens by using gdb
and setting a breakpoint at the malloc
function. Skip the first 2 hits of this breakpoint, and look at the stack trace when it gets hit for the 3rd time:
$ gcc -Wall -I /inst-json-c/20240329/include/json-c foo.c /inst-json-c/20240329/lib/libjson-c.a -lbsd -ggdb
$ ./a.out
before
after: j == NULL, jerrno == json_tokener_success
$ gdb a.out
GNU gdb (GDB) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...
(gdb) break main
Breakpoint 1 at 0x2678: file foo.c, line 18.
(gdb) break malloc
Breakpoint 2 at 0x2639: file foo.c, line 11.
(gdb) run
Starting program: /home/bruno/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at foo.c:19
18 {
(gdb) continue
Continuing.
before
Breakpoint 2.1, malloc (n=32) at foo.c:12
11 if (++counter <= 2)
(gdb) continue
Continuing.
Breakpoint 2.2, 0x00007ffff7dfe0a0 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) continue
Continuing.
Breakpoint 2.1, malloc (n=232) at foo.c:12
11 if (++counter <= 2)
(gdb) continue
Continuing.
Breakpoint 2.2, 0x00007ffff7dfe0a0 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) continue
Continuing.
Breakpoint 2.1, malloc (n=232) at foo.c:12
11 if (++counter <= 2)
(gdb) print counter
$1 = 2
(gdb) where
#0 malloc (n=232) at foo.c:12
#1 0x00007ffff7d92120 in newlocale () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x0000555555556c79 in json_tokener_parse_ex (tok=0x5555555682a0, str=0x555555562013 "{ \"a\": 1 }", len=-1)
at /source/newest/json/json-c/json_tokener.c:344
#3 0x0000555555556b3e in json_tokener_parse_verbose (str=0x555555562013 "{ \"a\": 1 }", error=0x7fffffffd714)
at /source/newest/json/json-c/json_tokener.c:233
#4 0x00005555555566da in main () at foo.c:23
from json-c.
There are surely other code paths that lead to memory allocation failures. To get them, change the line
if (++counter <= 2)
to
if (++counter <= 3)
then
if (++counter <= 4)
and so on.
from json-c.
Found and fixed a few places, using an enhanced version of the test driver:
#define _GNU_SOURCE 1
#include <stdlib.h>
#include <unistd.h>
#include <dlfcn.h>
#include <json.h>
#include <limits.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
static int counter_limit = 0;
static int limit_hit = 0;
void * (* libc_malloc) (size_t);
int counter = 0;
/* This malloc function works normally in the first two memory allocations, and returns NULL afterwards. */
void *malloc (size_t n)
{
if (!counter_limit || ++counter <= counter_limit)
return libc_malloc (n);
if (!limit_hit)
limit_hit = counter;
return NULL;
}
int main (int argc, char **argv)
{
libc_malloc = dlsym (RTLD_NEXT, "malloc");
if (argc < 3)
{
printf("Usage: <jsonfile> <counterlimit>\n");
exit(1);
}
write (1, "before\n", 7);
enum json_tokener_error jerrno = -1;
int fd = open(argv[1], O_RDONLY);
struct stat fdinfo;
if (fd < 0)
{
printf("open error: %s\n", strerror(errno));
exit(1);
}
if (fstat(fd, &fdinfo) < 0)
{
printf("stat error: %s\n", strerror(errno));
exit(1);
}
char *mem = malloc(fdinfo.st_size + 1);
if (read(fd, mem, fdinfo.st_size) != fdinfo.st_size)
{
printf("read error: %s\n", strerror(errno));
exit(1);
}
counter_limit = atoi(argv[2]);
struct json_object *j = json_tokener_parse_verbose (mem, &jerrno);
counter_limit = 0;
char message[] = "after: j == NULL, jerrno == json_tokener_success\n";
message[9] = (j != NULL ? '!' : '=');
message[25] = (jerrno != json_tokener_success ? '!' : '=');
write (1, message, 49);
if (limit_hit)
printf("Limit hit at %d\n", limit_hit);
if (jerrno != json_tokener_error_memory)
return 1;
return 0;
}
from json-c.
Thanks!
By code inspection, I found another place where an out-of-memory can happen, and opened #861 .
from json-c.
Related Issues (20)
- Cannot link properly using cmake HOT 2
- Memory leak when enable HAVE_SETLOCALE and HAVE_USELOCALE HOT 2
- Random crash in json_tokener_parse HOT 7
- Assignment bug in json_pointer.c HOT 2
- _WIN32 should be used, not WIN32 in source code ifdefs. HOT 2
- Doxygen: mis-wording in `json_object_put`
- json_object_from_file caused calloc SIGSEGV HOT 2
- Missing return description
- Allow NULL in json_object_new_string() and json_object_new_string_len() HOT 3
- json_tokener_parse_verbose does not set the error indicator when it fails to allocate the tokener HOT 3
- json_tokener_parse_verbose sets the error indicator to a wrong value when there is a memory allocation failure HOT 3
- json_tokener_parse is not multithread-safe on some platforms HOT 10
- Using libjson-c.so or compiling from source seg faults on json_tokener_parse_ex in alpine docker container HOT 4
- Missing `json-c-targets.cmake` during build cmake build step HOT 1
- build ios simulator error HOT 4
- Assertion usage HOT 2
- Parsing of control characters
- I meet compile error in harmony HOT 3
- At a high level how are jsons parses? Are they terminated by the new line? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from json-c.