#include #include #include #include #include "afl-fuzz.h" #include "gramfuzz.h" #ifdef _GNU_SOURCE #undef _GNU_SOURCE #endif #define _GNU_SOURCE #include /* Dynamic Array for adding to the input repr * */ void initArray(Array *a, size_t initialSize) { a->start = (terminal *)calloc(1, sizeof(terminal) * initialSize); a->used = 0; a->size = initialSize; a->inputlen = 0; } void insertArray(Array *a, int state, char *symbol, size_t symbol_len, int trigger_idx) { // a->used is the number of used entries, because a->array[a->used++] updates // a->used only *after* the array has been accessed. Therefore a->used can go // up to a->size terminal *term_ptr; if (a->used == a->size) { a->size = a->size * sizeof(terminal); a->start = (terminal *)realloc(a->start, a->size * sizeof(terminal)); } // Add the element term_ptr = &a->start[a->used]; term_ptr->state = state; term_ptr->symbol = symbol; term_ptr->symbol_len = symbol_len; term_ptr->trigger_idx = trigger_idx; // Increment the pointer a->used += 1; a->inputlen += symbol_len; } void freeArray(Array *a) { terminal *ptr; for (int x = 0; x < a->used; x++) { ptr = &a->start[x]; free(ptr); } a->start = NULL; a->used = a->size = 0; } /* Dynamic array for adding indices of states/recursive features * Source: * https://stackoverflow.com/questions/3536153/c-dynamically-growing-array */ void initArrayIdx(IdxMap *a, size_t initialSize) { a->array = (int *)malloc(initialSize * sizeof(int)); a->used = 0; a->size = initialSize; } void insertArrayIdx(IdxMap *a, int idx) { // a->used is the number of used entries, because a->array[a->used++] updates // a->used only *after* the array has been accessed. Therefore a->used can go // up to a->size if (a->used == a->size) { a->size *= 2; a->array = (int *)realloc(a->array, a->size * sizeof(int)); } a->array[a->used++] = idx; } void freeArrayIdx(IdxMap *a) { free(a->array); a->array = NULL; a->used = a->size = 0; } /* Dynamic array for adding potential splice points */ void initArraySplice(SpliceCandArray *a, size_t initialSize) { a->start = (SpliceCand *)malloc(initialSize * sizeof(SpliceCand)); a->used = 0; a->size = initialSize; } void insertArraySplice(SpliceCandArray *a, Candidate *candidate, int idx) { // a->used is the number of used entries, because a->array[a->used++] updates // a->used only *after* the array has been accessed. Therefore a->used can go // up to a->size SpliceCand *candptr; if (a->used == a->size) { a->size = a->size * sizeof(SpliceCand); a->start = (SpliceCand *)realloc(a->start, a->size * sizeof(SpliceCand)); } // Add the element candptr = &a->start[a->used]; candptr->splice_cand = candidate; candptr->idx = idx; a->used += 1; } void freeArraySplice(IdxMap *a) { free(a->array); a->array = NULL; a->used = a->size = 0; } int fact(int n) { int i, f = 1; for (i = 1; i <= n; i++) { f *= i; } return f; } /* Uses the walk to create the input in-memory */ u8 *unparse_walk(Array *input) { terminal *term_ptr; int offset = 0; u8 * unparsed = (u8 *)malloc(input->inputlen + 1); term_ptr = &input->start[offset]; strcpy(unparsed, term_ptr->symbol); offset += 1; while (offset < input->used) { term_ptr = &input->start[offset]; strcat(unparsed, term_ptr->symbol); offset += 1; } return unparsed; } /*Dump the input representation into a file*/ void write_input(Array *input, u8 *fn) { FILE *fp; // If file already exists, then skip creating the file if (access(fn, F_OK) != -1) { return; } fp = fopen(fn, "wbx+"); // If the input has already been flushed, then skip silently if (fp == NULL) { fprintf(stderr, "\n File '%s' could not be open, exiting\n", fn); exit(1); } // Write the length parameters fwrite(&input->used, sizeof(size_t), 1, fp); fwrite(&input->size, sizeof(size_t), 1, fp); fwrite(&input->inputlen, sizeof(size_t), 1, fp); // Write the dynamic array to file fwrite(input->start, input->size * sizeof(terminal), 1, fp); // printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size, // input->inputlen); fclose(fp); } Array *parse_input(state *pda, FILE *fp) { terminal *term; state * state_ptr; trigger * trigger; int trigger_idx; Array * input = (Array *)calloc(1, sizeof(Array)); // Read the length parameters fread(&input->used, sizeof(size_t), 1, fp); fread(&input->size, sizeof(size_t), 1, fp); fread(&input->inputlen, sizeof(size_t), 1, fp); terminal *start_ptr = (terminal *)calloc(input->size, sizeof(terminal)); if (!start_ptr) { fprintf(stderr, "alloc failed!\n"); return NULL; } // Read the dynamic array to memory fread(start_ptr, input->size * sizeof(terminal), 1, fp); // Update the pointers to the terminals since they would have // changed int idx = 0; while (idx < input->used) { terminal *term = &start_ptr[idx]; // Find the state state_ptr = pda + term->state; // Find the trigger and update the terminal address trigger_idx = term->trigger_idx; trigger = (state_ptr->ptr) + trigger_idx; term->symbol = trigger->term; idx += 1; } input->start = start_ptr; // printf("\nUsed:%zu Size:%zu Inputlen:%zu", input->used, input->size, // input->inputlen); return input; } // Read the input representation into memory Array *read_input(state *pda, u8 *fn) { FILE *fp; fp = fopen(fn, "rb"); if (fp == NULL) { fprintf(stderr, "\n File '%s' does not exist, exiting\n", fn); exit(1); } Array *res = parse_input(pda, fp); fclose(fp); return res; }