| 390 | } |
| 391 | |
| 392 | static size_t __mutate_array_fixed(ParcelData* entry, FuzzParcel* input, size_t MaxSize, size_t elementSize){ |
| 393 | //TODO: mutate lenght with certain probability |
| 394 | size_t ArraySizeChange = rand() % (MAX_BUF_SIZE/elementSize); |
| 395 | size_t AddSize = ArraySizeChange*elementSize; |
| 396 | if(AddSize != 0){ |
| 397 | unsigned char* new_buf = (unsigned char*)realloc(entry->buf, AddSize + entry->buf_size); |
| 398 | if(!new_buf){ |
| 399 | LOGD("failed to realloc!\n"); |
| 400 | return -1; |
| 401 | } |
| 402 | entry->buf = new_buf; |
| 403 | } |
| 404 | auto M = (*DefaultMutators)[rand() % NrDefaultMutators]; |
| 405 | LOGD("var length: mutator chosen to mutate entry: %s\n", M.Name); |
| 406 | size_t NewSize = M.Fn(MutationDispatcher, entry->buf, entry->buf_size, entry->buf_size+AddSize); |
| 407 | if(NewSize == 0){ |
| 408 | return -1; //Mutation failed |
| 409 | } |
| 410 | if(NewSize + (input->buf_size - entry->buf_size) + 2*sizeof(uint32_t) > MaxSize){ |
| 411 | return -1; //serialized size will exceed the libfuzzers maxsize |
| 412 | } |
| 413 | size_t NewArraySize; |
| 414 | if(NewSize != entry->buf_size){ |
| 415 | // ensure new buffer size is still consistent |
| 416 | // we know the new buffer is aligned correctly and has enough space |
| 417 | LOGD("__mutate_array_fixed changed lenght of array, NewSize: %ld, \ |
| 418 | input->buf_size: %d, entry->buf_size: %d\n", NewSize, input->buf_size, entry->buf_size); |
| 419 | NewArraySize = NewSize - (NewSize % elementSize); |
| 420 | // update the buffer sizes |
| 421 | input->buf_size = input->buf_size - entry->buf_size + NewArraySize; |
| 422 | entry->buf_size = NewArraySize; //change the buffer size |
| 423 | LOGD("__mutate_array_fixed buf_size NewArraySize: %zu, input->buf_size: %d, entry->buf_size: %d\n", |
| 424 | NewArraySize, input->buf_size, entry->buf_size); |
| 425 | } else { |
| 426 | NewArraySize = NewSize; |
| 427 | } |
| 428 | return NewArraySize; |
| 429 | } |
| 430 | |
| 431 | static size_t __mutate_array_var(ParcelData* entry, FuzzParcel* input, size_t MaxSize){ |
| 432 | uint32_t do_mutate_size = rand() % 10; |