|
@@ -24,54 +24,71 @@
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
|
|
-#include "../cJSON.h"
|
|
|
|
|
|
+#include "fuzz-target.h"
|
|
|
|
|
|
-static char *read_file(const char *filename)
|
|
|
|
|
|
+static char *read_file(const char *filename, size_t *size)
|
|
{
|
|
{
|
|
FILE *file = NULL;
|
|
FILE *file = NULL;
|
|
long length = 0;
|
|
long length = 0;
|
|
char *content = NULL;
|
|
char *content = NULL;
|
|
size_t read_chars = 0;
|
|
size_t read_chars = 0;
|
|
|
|
|
|
|
|
+ if (size == NULL)
|
|
|
|
+ {
|
|
|
|
+ goto fail;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* open in read binary mode */
|
|
/* open in read binary mode */
|
|
file = fopen(filename, "rb");
|
|
file = fopen(filename, "rb");
|
|
if (file == NULL)
|
|
if (file == NULL)
|
|
{
|
|
{
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
|
|
|
|
/* get the length */
|
|
/* get the length */
|
|
if (fseek(file, 0, SEEK_END) != 0)
|
|
if (fseek(file, 0, SEEK_END) != 0)
|
|
{
|
|
{
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
length = ftell(file);
|
|
length = ftell(file);
|
|
if (length < 0)
|
|
if (length < 0)
|
|
{
|
|
{
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
if (fseek(file, 0, SEEK_SET) != 0)
|
|
if (fseek(file, 0, SEEK_SET) != 0)
|
|
{
|
|
{
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
|
|
|
|
/* allocate content buffer */
|
|
/* allocate content buffer */
|
|
content = (char*)malloc((size_t)length + sizeof(""));
|
|
content = (char*)malloc((size_t)length + sizeof(""));
|
|
if (content == NULL)
|
|
if (content == NULL)
|
|
{
|
|
{
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
|
|
|
|
/* read the file into memory */
|
|
/* read the file into memory */
|
|
read_chars = fread(content, sizeof(char), (size_t)length, file);
|
|
read_chars = fread(content, sizeof(char), (size_t)length, file);
|
|
if ((long)read_chars != length)
|
|
if ((long)read_chars != length)
|
|
{
|
|
{
|
|
- free(content);
|
|
|
|
- content = NULL;
|
|
|
|
- goto cleanup;
|
|
|
|
|
|
+ goto fail;
|
|
}
|
|
}
|
|
content[read_chars] = '\0';
|
|
content[read_chars] = '\0';
|
|
|
|
|
|
|
|
+ *size = read_chars + sizeof("");
|
|
|
|
+
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+fail:
|
|
|
|
+ if (size != NULL)
|
|
|
|
+ {
|
|
|
|
+ *size = 0;
|
|
|
|
+ }
|
|
|
|
+ if (content != NULL)
|
|
|
|
+ {
|
|
|
|
+ free(content);
|
|
|
|
+ content = NULL;
|
|
|
|
+ }
|
|
|
|
|
|
cleanup:
|
|
cleanup:
|
|
if (file != NULL)
|
|
if (file != NULL)
|
|
@@ -85,92 +102,50 @@ cleanup:
|
|
int main(int argc, char** argv)
|
|
int main(int argc, char** argv)
|
|
{
|
|
{
|
|
const char *filename = NULL;
|
|
const char *filename = NULL;
|
|
- cJSON *item = NULL;
|
|
|
|
char *json = NULL;
|
|
char *json = NULL;
|
|
int status = EXIT_FAILURE;
|
|
int status = EXIT_FAILURE;
|
|
char *printed_json = NULL;
|
|
char *printed_json = NULL;
|
|
|
|
|
|
- if ((argc < 2) || (argc > 3))
|
|
|
|
|
|
+ if (argc != 2)
|
|
{
|
|
{
|
|
printf("Usage:\n");
|
|
printf("Usage:\n");
|
|
- printf("%s input_file [enable_printing]\n", argv[0]);
|
|
|
|
|
|
+ printf("%s input_file\n", argv[0]);
|
|
printf("\t input_file: file containing the test data\n");
|
|
printf("\t input_file: file containing the test data\n");
|
|
- printf("\t enable_printing: print after parsing, 'yes' or 'no', defaults to 'no'\n");
|
|
|
|
goto cleanup;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
|
|
filename = argv[1];
|
|
filename = argv[1];
|
|
|
|
|
|
-#if __AFL_HAVE_MANUAL_CONTROL
|
|
|
|
|
|
+#if defined(__AFL_HAVE_MANUAL_CONTROL) && __AFL_HAVE_MANUAL_CONTROL
|
|
while (__AFL_LOOP(1000))
|
|
while (__AFL_LOOP(1000))
|
|
{
|
|
{
|
|
-#endif
|
|
|
|
- status = EXIT_SUCCESS;
|
|
|
|
-
|
|
|
|
- json = read_file(filename);
|
|
|
|
- if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0'))
|
|
|
|
|
|
+#else
|
|
{
|
|
{
|
|
- status = EXIT_FAILURE;
|
|
|
|
- goto cleanup;
|
|
|
|
- }
|
|
|
|
- item = cJSON_Parse(json + 2);
|
|
|
|
- if (item == NULL)
|
|
|
|
- {
|
|
|
|
- goto cleanup;
|
|
|
|
- }
|
|
|
|
|
|
+#endif
|
|
|
|
+ size_t size = 0;
|
|
|
|
+ status = EXIT_SUCCESS;
|
|
|
|
|
|
- if ((argc == 3) && (strncmp(argv[2], "yes", 3) == 0))
|
|
|
|
- {
|
|
|
|
- int do_format = 0;
|
|
|
|
- if (json[1] == 'f')
|
|
|
|
|
|
+ json = read_file(filename, &size);
|
|
|
|
+ if ((json == NULL) || (json[0] == '\0') || (json[1] == '\0'))
|
|
{
|
|
{
|
|
- do_format = 1;
|
|
|
|
|
|
+ status = EXIT_FAILURE;
|
|
|
|
+ goto cleanup;
|
|
}
|
|
}
|
|
|
|
|
|
- if (json[0] == 'b')
|
|
|
|
- {
|
|
|
|
- /* buffered printing */
|
|
|
|
- printed_json = cJSON_PrintBuffered(item, 1, do_format);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
|
|
+ LLVMFuzzerTestOneInput(json, size);
|
|
|
|
+
|
|
|
|
+ cleanup:
|
|
|
|
+ if (json != NULL)
|
|
{
|
|
{
|
|
- /* unbuffered printing */
|
|
|
|
- if (do_format)
|
|
|
|
- {
|
|
|
|
- printed_json = cJSON_Print(item);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- printed_json = cJSON_PrintUnformatted(item);
|
|
|
|
- }
|
|
|
|
|
|
+ free(json);
|
|
|
|
+ json = NULL;
|
|
}
|
|
}
|
|
- if (printed_json == NULL)
|
|
|
|
|
|
+ if (printed_json != NULL)
|
|
{
|
|
{
|
|
- status = EXIT_FAILURE;
|
|
|
|
- goto cleanup;
|
|
|
|
|
|
+ free(printed_json);
|
|
|
|
+ printed_json = NULL;
|
|
}
|
|
}
|
|
- printf("%s\n", printed_json);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-cleanup:
|
|
|
|
- if (item != NULL)
|
|
|
|
- {
|
|
|
|
- cJSON_Delete(item);
|
|
|
|
- item = NULL;
|
|
|
|
}
|
|
}
|
|
- if (json != NULL)
|
|
|
|
- {
|
|
|
|
- free(json);
|
|
|
|
- json = NULL;
|
|
|
|
- }
|
|
|
|
- if (printed_json != NULL)
|
|
|
|
- {
|
|
|
|
- free(printed_json);
|
|
|
|
- printed_json = NULL;
|
|
|
|
- }
|
|
|
|
-#if __AFL_HAVE_MANUAL_CONTROL
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
|
|
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|