19750e409Sopenharmony_ci/*
29750e409Sopenharmony_ci  Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
39750e409Sopenharmony_ci
49750e409Sopenharmony_ci  Permission is hereby granted, free of charge, to any person obtaining a copy
59750e409Sopenharmony_ci  of this software and associated documentation files (the "Software"), to deal
69750e409Sopenharmony_ci  in the Software without restriction, including without limitation the rights
79750e409Sopenharmony_ci  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
89750e409Sopenharmony_ci  copies of the Software, and to permit persons to whom the Software is
99750e409Sopenharmony_ci  furnished to do so, subject to the following conditions:
109750e409Sopenharmony_ci
119750e409Sopenharmony_ci  The above copyright notice and this permission notice shall be included in
129750e409Sopenharmony_ci  all copies or substantial portions of the Software.
139750e409Sopenharmony_ci
149750e409Sopenharmony_ci  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
159750e409Sopenharmony_ci  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
169750e409Sopenharmony_ci  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
179750e409Sopenharmony_ci  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
189750e409Sopenharmony_ci  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
199750e409Sopenharmony_ci  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
209750e409Sopenharmony_ci  THE SOFTWARE.
219750e409Sopenharmony_ci*/
229750e409Sopenharmony_ci
239750e409Sopenharmony_ci#include <stdio.h>
249750e409Sopenharmony_ci#include <stdlib.h>
259750e409Sopenharmony_ci#include <string.h>
269750e409Sopenharmony_ci
279750e409Sopenharmony_ci#include "../cJSON.h"
289750e409Sopenharmony_ci
299750e409Sopenharmony_cistatic char *read_file(const char *filename)
309750e409Sopenharmony_ci{
319750e409Sopenharmony_ci    FILE *file = NULL;
329750e409Sopenharmony_ci    long length = 0;
339750e409Sopenharmony_ci    char *content = NULL;
349750e409Sopenharmony_ci    size_t read_chars = 0;
359750e409Sopenharmony_ci
369750e409Sopenharmony_ci    /* open in read binary mode */
379750e409Sopenharmony_ci    file = fopen(filename, "rb");
389750e409Sopenharmony_ci    if (file == NULL)
399750e409Sopenharmony_ci    {
409750e409Sopenharmony_ci        goto cleanup;
419750e409Sopenharmony_ci    }
429750e409Sopenharmony_ci
439750e409Sopenharmony_ci    /* get the length */
449750e409Sopenharmony_ci    if (fseek(file, 0, SEEK_END) != 0)
459750e409Sopenharmony_ci    {
469750e409Sopenharmony_ci        goto cleanup;
479750e409Sopenharmony_ci    }
489750e409Sopenharmony_ci    length = ftell(file);
499750e409Sopenharmony_ci    if (length < 0)
509750e409Sopenharmony_ci    {
519750e409Sopenharmony_ci        goto cleanup;
529750e409Sopenharmony_ci    }
539750e409Sopenharmony_ci    if (fseek(file, 0, SEEK_SET) != 0)
549750e409Sopenharmony_ci    {
559750e409Sopenharmony_ci        goto cleanup;
569750e409Sopenharmony_ci    }
579750e409Sopenharmony_ci
589750e409Sopenharmony_ci    /* allocate content buffer */
599750e409Sopenharmony_ci    content = (char*)malloc((size_t)length + sizeof(""));
609750e409Sopenharmony_ci    if (content == NULL)
619750e409Sopenharmony_ci    {
629750e409Sopenharmony_ci        goto cleanup;
639750e409Sopenharmony_ci    }
649750e409Sopenharmony_ci
659750e409Sopenharmony_ci    /* read the file into memory */
669750e409Sopenharmony_ci    read_chars = fread(content, sizeof(char), (size_t)length, file);
679750e409Sopenharmony_ci    if ((long)read_chars != length)
689750e409Sopenharmony_ci    {
699750e409Sopenharmony_ci        free(content);
709750e409Sopenharmony_ci        content = NULL;
719750e409Sopenharmony_ci        goto cleanup;
729750e409Sopenharmony_ci    }
739750e409Sopenharmony_ci    content[read_chars] = '\0';
749750e409Sopenharmony_ci
759750e409Sopenharmony_ci
769750e409Sopenharmony_cicleanup:
779750e409Sopenharmony_ci    if (file != NULL)
789750e409Sopenharmony_ci    {
799750e409Sopenharmony_ci        fclose(file);
809750e409Sopenharmony_ci    }
819750e409Sopenharmony_ci
829750e409Sopenharmony_ci    return content;
839750e409Sopenharmony_ci}
849750e409Sopenharmony_ci
859750e409Sopenharmony_ciint main(int argc, char** argv)
869750e409Sopenharmony_ci{
879750e409Sopenharmony_ci    const char *filename = NULL;
889750e409Sopenharmony_ci    cJSON *item = NULL;
899750e409Sopenharmony_ci    char *json = NULL;
909750e409Sopenharmony_ci    int status = EXIT_FAILURE;
919750e409Sopenharmony_ci    char *printed_json = NULL;
929750e409Sopenharmony_ci
939750e409Sopenharmony_ci    if ((argc < 2) || (argc > 3))
949750e409Sopenharmony_ci    {
959750e409Sopenharmony_ci        printf("Usage:\n");
969750e409Sopenharmony_ci        printf("%s input_file [enable_printing]\n", argv[0]);
979750e409Sopenharmony_ci        printf("\t input_file: file containing the test data\n");
989750e409Sopenharmony_ci        printf("\t enable_printing: print after parsing, 'yes' or 'no', defaults to 'no'\n");
999750e409Sopenharmony_ci        goto cleanup;
1009750e409Sopenharmony_ci    }
1019750e409Sopenharmony_ci
1029750e409Sopenharmony_ci    filename = argv[1];
1039750e409Sopenharmony_ci
1049750e409Sopenharmony_ci#if __AFL_HAVE_MANUAL_CONTROL
1059750e409Sopenharmony_ci    while (__AFL_LOOP(1000))
1069750e409Sopenharmony_ci    {
1079750e409Sopenharmony_ci#endif
1089750e409Sopenharmony_ci    status = EXIT_SUCCESS;
1099750e409Sopenharmony_ci
1109750e409Sopenharmony_ci    json = read_file(filename);
1119750e409Sopenharmony_ci    if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0'))
1129750e409Sopenharmony_ci    {
1139750e409Sopenharmony_ci        status = EXIT_FAILURE;
1149750e409Sopenharmony_ci        goto cleanup;
1159750e409Sopenharmony_ci    }
1169750e409Sopenharmony_ci    item = cJSON_Parse(json + 2);
1179750e409Sopenharmony_ci    if (item == NULL)
1189750e409Sopenharmony_ci    {
1199750e409Sopenharmony_ci        goto cleanup;
1209750e409Sopenharmony_ci    }
1219750e409Sopenharmony_ci
1229750e409Sopenharmony_ci    if ((argc == 3) && (strncmp(argv[2], "yes", 3) == 0))
1239750e409Sopenharmony_ci    {
1249750e409Sopenharmony_ci        int do_format = 0;
1259750e409Sopenharmony_ci        if (json[1] == 'f')
1269750e409Sopenharmony_ci        {
1279750e409Sopenharmony_ci            do_format = 1;
1289750e409Sopenharmony_ci        }
1299750e409Sopenharmony_ci
1309750e409Sopenharmony_ci        if (json[0] == 'b')
1319750e409Sopenharmony_ci        {
1329750e409Sopenharmony_ci            /* buffered printing */
1339750e409Sopenharmony_ci            printed_json = cJSON_PrintBuffered(item, 1, do_format);
1349750e409Sopenharmony_ci        }
1359750e409Sopenharmony_ci        else
1369750e409Sopenharmony_ci        {
1379750e409Sopenharmony_ci            /* unbuffered printing */
1389750e409Sopenharmony_ci            if (do_format)
1399750e409Sopenharmony_ci            {
1409750e409Sopenharmony_ci                printed_json = cJSON_Print(item);
1419750e409Sopenharmony_ci            }
1429750e409Sopenharmony_ci            else
1439750e409Sopenharmony_ci            {
1449750e409Sopenharmony_ci                printed_json = cJSON_PrintUnformatted(item);
1459750e409Sopenharmony_ci            }
1469750e409Sopenharmony_ci        }
1479750e409Sopenharmony_ci        if (printed_json == NULL)
1489750e409Sopenharmony_ci        {
1499750e409Sopenharmony_ci            status = EXIT_FAILURE;
1509750e409Sopenharmony_ci            goto cleanup;
1519750e409Sopenharmony_ci        }
1529750e409Sopenharmony_ci        printf("%s\n", printed_json);
1539750e409Sopenharmony_ci    }
1549750e409Sopenharmony_ci
1559750e409Sopenharmony_cicleanup:
1569750e409Sopenharmony_ci    if (item != NULL)
1579750e409Sopenharmony_ci    {
1589750e409Sopenharmony_ci        cJSON_Delete(item);
1599750e409Sopenharmony_ci        item = NULL;
1609750e409Sopenharmony_ci    }
1619750e409Sopenharmony_ci    if (json != NULL)
1629750e409Sopenharmony_ci    {
1639750e409Sopenharmony_ci        free(json);
1649750e409Sopenharmony_ci        json = NULL;
1659750e409Sopenharmony_ci    }
1669750e409Sopenharmony_ci    if (printed_json != NULL)
1679750e409Sopenharmony_ci    {
1689750e409Sopenharmony_ci        free(printed_json);
1699750e409Sopenharmony_ci        printed_json = NULL;
1709750e409Sopenharmony_ci    }
1719750e409Sopenharmony_ci#if __AFL_HAVE_MANUAL_CONTROL
1729750e409Sopenharmony_ci    }
1739750e409Sopenharmony_ci#endif
1749750e409Sopenharmony_ci
1759750e409Sopenharmony_ci    return status;
1769750e409Sopenharmony_ci}
177