| 429 | } |
| 430 | |
| 431 | static size_t __mutate_array_var(ParcelData* entry, FuzzParcel* input, size_t MaxSize){ |
| 432 | uint32_t do_mutate_size = rand() % 10; |
| 433 | VarSizeArrayEntry* varEntry = (VarSizeArrayEntry*)entry->buf; |
| 434 | if(do_mutate_size == 0){ |
| 435 | //mutate the size of the array |
| 436 | uint32_t newSize = (rand() % 42) + 1; |
| 437 | LOGD("__mutate_array_var new size: %d\n", newSize); |
| 438 | if(newSize == varEntry->nrEntries){ |
| 439 | LOGD("__mutate_array_var size is the same: newSize %d, prev size: %d\n", newSize, varEntry->nrEntries); |
| 440 | return newSize; |
| 441 | } |
| 442 | if(newSize < varEntry->nrEntries){ |
| 443 | LOGD("__mutate_array_var truncating array: newSize %d, prev size: %d\n", newSize, varEntry->nrEntries); |
| 444 | varEntry->nrEntries = newSize; |
| 445 | uint32_t new_data_size = 0; |
| 446 | uint32_t offset = 0; |
| 447 | for(int i=0; i<varEntry->nrEntries; i++){ |
| 448 | LenValData* lvd = (LenValData*)&varEntry->data[offset]; |
| 449 | new_data_size += lvd->size; |
| 450 | offset += sizeof(uint32_t) + lvd->size; |
| 451 | } |
| 452 | varEntry->size = new_data_size; |
| 453 | return newSize; |
| 454 | } else { |
| 455 | //terrible logic to add new entries |
| 456 | uint32_t toAdd = newSize - varEntry->nrEntries ; |
| 457 | LOGD("__mutate_array_var adding %d new entries\n", toAdd); |
| 458 | uint32_t* sizes = (uint32_t*)malloc(toAdd*sizeof(uint32_t)); |
| 459 | uint32_t sizeNew = 0; |
| 460 | for(int i=0; i<toAdd; i++){ |
| 461 | sizes[i] = rand() % 42 + 1; |
| 462 | sizeNew += sizes[i]; |
| 463 | } |
| 464 | uint32_t new_data_size = sizeNew + varEntry->size; |
| 465 | if(input->buf_size - entry->buf_size + 2*sizeof(uint32_t) + ((2+varEntry->nrEntries)*sizeof(uint32_t)+new_data_size) > MaxSize){ |
| 466 | free(sizes); |
| 467 | return -1; |
| 468 | } |
| 469 | varEntry = (VarSizeArrayEntry*)realloc(varEntry, new_data_size + (2+newSize)*sizeof(uint32_t)); |
| 470 | uint32_t offset = sizeof(uint32_t)*varEntry->nrEntries + varEntry->size; |
| 471 | for(int i=0; i<toAdd; i++){ |
| 472 | LenValData* lvd = (LenValData*)&varEntry->data[offset]; |
| 473 | LOGD("adding new var buf entry at offset: %d, %p\n", offset, lvd); |
| 474 | lvd->size = sizes[i]; |
| 475 | __random_fill_buffer(lvd->data, sizes[i]); |
| 476 | offset += sizeof(uint32_t) + lvd->size; |
| 477 | } |
| 478 | varEntry->nrEntries = newSize; |
| 479 | varEntry->size = new_data_size; |
| 480 | entry->buf = (uint8_t*)varEntry; |
| 481 | entry->buf_size = (2+varEntry->nrEntries)*sizeof(uint32_t)+varEntry->size; //nrentries,size,size for each entry + overall data size |
| 482 | free(sizes); |
| 483 | return entry->buf_size; |
| 484 | } |
| 485 | } else { |
| 486 | //mutate single entry |
| 487 | uint32_t idx = rand() % varEntry->nrEntries; |
| 488 | //TODO support changing the size of individual entries |
no test coverage detected