Core dump when parsing JSON data from pipe using Jansson

87 Views Asked by At

EDIT - Added a minimal reproducible code

I am trying to read some json data from a named pipe. I need to parse the json in C and I am using Jansson library to do so. However, when I try to parse the json objects, I get a core dump error.

Example JSON Data:

{
    "object_ids": [0], 
    "object_classes": ["Person"], 
    "confidences": [0.5], 
    "bounding_boxes": [[0.49161258339881897, 0.40708258748054504, 0.10166069865226746, 0.30669090151786804]]
}

The code snippet used to parse through it (Note this is a part of a bigger code, but this should work ):

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <jansson.h>

// A pipe has already been created prior to execution of the code
#define PIPE_NAME "/tmp/xyz"

typedef struct {
    int obj_ids[MAX_ENTRIES];
    char obj_names[MAX_ENTRIES][16];
    double conf[MAX_ENTRIES];
    double coords[MAX_ENTRIES][4];
} ConvertedData;

static ConvertedData *converted_data = NULL;

int main() {
    // A buffer to store read from the pipe
    char buffer[4096];
    
    int fd = open(PIPE_NAME, O_RDONLY);
        if (fd == -1) {
            perror("Error opening named pipe");
            exit(EXIT_FAILURE);
        }

        // Read data from the named pipe
        ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
        if (bytesRead == -1) {
            perror("Error reading from named pipe");
            close(fd);
        }
    
    json_error_t error;
        json_t *obj = json_loads(buffer, 0, &error);

        if (!obj) {
            syslog(LOG_ERR, "ERROR: json object on line %d: %s\n", error.line, error.text);
        }
        else {
            json_t *obj_ids = json_object_get(obj, "object_ids");
            json_incref(obj_ids);
            json_t *classes = json_object_get(obj, "object_classes");
            json_incref(classes);
            json_t *confs = json_object_get(obj, "confidences");
            json_incref(confs);
            json_t *bboxes = json_object_get(obj, "bounding_boxes");
            json_incref(bboxes);

            if (json_is_array(obj_ids) && json_is_array(classes) && 
            json_is_array(confs) && json_is_array(bboxes)) {
                syslog(LOG_INFO, "Inside IF");

                size_t arr_size = json_array_size(confs);

                for(size_t i = 0; i < arr_size; i++) {
                    syslog(LOG_INFO, "Inside Loop");
                    // Store the Object IDS
                    converted_data->obj_ids[i] = json_integer_value(json_array_get(obj_ids, i));

                    // Store the Object Names
                    const char *obj_class = json_string_value(json_array_get(classes, i));
                    strncpy(converted_data->obj_names[i], obj_class, sizeof(converted_data->obj_names[i]) -1);
                    converted_data->obj_names[i][sizeof(converted_data->obj_names[i]) -1] = '\0';
                    
                    // Store the Bounding Boxes
                    json_t *bbox = json_array_get(bboxes, i);
                    json_incref(bbox);
                    if(json_is_array(bbox) && json_array_size(bbox) == 4) {
                        for(size_t j = 0; j < 4; j++) {
                            converted_data->coords[i][j] = json_real_value(json_array_get(bbox, j));
                        }
                    }
                    json_decref(bbox);

                    converted_data->conf[i] = json_real_value(json_array_get(confs, i));
                }
            }
            else {
                syslog(LOG_ERR, "ERROR: Incorrect JSON data structure");
            }

            json_decref(obj_ids);
            json_decref(classes);
            json_decref(confs);
            json_decref(bboxes);
            json_decref(obj);
        }
        
        // Further Processing
    
    return 0;
}

Note that as soon as the loop starts, I get a core dump. What am I doing wrong?

EDIT:

After some debugging, the error occurs when I try to store the data in the struct.

1

There are 1 best solutions below

2
On BEST ANSWER

I modified program to read JSON from stdin and added:

#include <syslog.h>
#define MAX_ENTRIES 42
#define syslog(level, ...) printf(__VA_ARGS__)

The program segfaults on:

0x00005555555554a0 in main () at your.c:60
60                          converted_data->obj_ids[i] = json_integer_value(json_array_get(obj_ids, i));

converted_data is a NULL pointer. Allocate an object, for example, by moving the variable to main():

ConvertedData *converted_data = &(ConvertedData) {0};

example session:

$ ./a.out < your.json
Inside IFInside Loop$