From 82fdb03c4cb9c76d151624352b5ecd86a3d6c94c Mon Sep 17 00:00:00 2001 From: Intel A80486DX2-66 Date: Tue, 19 Nov 2024 21:03:33 +0300 Subject: [PATCH] corrupter.c: extract `corrupt_byte` --- src/corrupter.c | 135 ++++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 57 deletions(-) diff --git a/src/corrupter.c b/src/corrupter.c index 1a013c0..c154fcc 100644 --- a/src/corrupter.c +++ b/src/corrupter.c @@ -1,5 +1,27 @@ #include "corrupter.h" +/* enums */ +enum Interoperation_Result { + INTEROPERATION_SUCCESS = false, + INTEROPERATION_ERROR = true +}; + +/* macros: definitions */ +#define Interoperation_Input_Vars \ + Corrupter_Param* param, Corrupter_Result* result, FILE* file, \ + file_offset_t i +#define Interoperation_Share_Vars \ + param, result, file, \ + i + +/* macros: lambdas */ +#define CORRUPT_BYTE_MACRO \ + if (corrupt_byte(Interoperation_Share_Vars) == INTEROPERATION_ERROR) { \ + result->error = true; \ + fclose(file); \ + return result; \ + } + /* cached operations */ const size_t UINT16_MAX_PLUS_1 = UINT16_MAX + 1; @@ -21,6 +43,60 @@ static bool is_line_ending(byte c) { return c == '\n' || c == '\r'; } +enum Interoperation_Result corrupt_byte(Interoperation_Input_Vars) { + uint8_t config = param->config; + + FSEEK_MACRO(file, i, SEEK_SET); + byte byte_value; + + if (fread(&byte_value, sizeof(byte), 1, file) != 1) + return INTEROPERATION_ERROR; + + if (READ_CONFIG(C_PRINTABLE) && !isprint(byte_value)) + return INTEROPERATION_SUCCESS; + else if (READ_CONFIG(C_LINE_ENDINGS) && is_line_ending(byte_value)) + return INTEROPERATION_SUCCESS; + + // generate bit mask + byte damage_left = param->threshold; + static bool bit_mask[CHAR_BIT]; + uint8_t probability = param->probability; + + for (byte bit = 0; bit < CHAR_BIT; bit++) { + if (get_chance(probability) && (damage_left > 0)) { + bit_mask[bit] = true; + damage_left--; + } else { + bit_mask[bit] = false; + } + } + + bool damaged_byte = false; + file_offset_t threshold = (file_offset_t) param->threshold; + + for (byte bit = 0; bit < threshold; bit++) { + if (bit_mask[bit] == false) + continue; + + byte_value = FLIP_BIT(byte_value, bit); + result->hit_counter++; + + damaged_byte = true; + + // write the modified byte back to the file + FSEEK_MACRO(file, i, SEEK_SET); + + if (fwrite(&byte_value, sizeof(byte), 1, file) != 1) + // on error + return INTEROPERATION_ERROR; + } + + if (damaged_byte) + result->damaged_bytes++; + + return INTEROPERATION_SUCCESS; +} + Corrupter_Result* corrupt_file(Corrupter_Param* param) { Corrupter_Result* result = malloc(sizeof(Corrupter_Result)); @@ -29,9 +105,6 @@ Corrupter_Result* corrupt_file(Corrupter_Param* param) { // copy and cast parameters FILE* file = param->file; - uint8_t probability = param->probability; - file_offset_t threshold = (file_offset_t) param->threshold; - uint8_t config = param->config; // refuse to operate on non-seekable streams if (FSEEK_MACRO(file, FILE_OFFSET_C(0), SEEK_SET) != 0 || @@ -84,60 +157,8 @@ Corrupter_Result* corrupt_file(Corrupter_Param* param) { rewind(file); // iterate over the file contents - for (file_offset_t i = start; i < end; i++) { - FSEEK_MACRO(file, i, SEEK_SET); - byte byte_value; - - if (fread(&byte_value, sizeof(byte), 1, file) != 1) { - result->error = true; - fclose(file); - return result; - } - - if (READ_CONFIG(C_PRINTABLE) && !isprint(byte_value)) - continue; - else if (READ_CONFIG(C_LINE_ENDINGS) && is_line_ending(byte_value)) - continue; - - // generate bit mask - byte damage_left = param->threshold; - static bool bit_mask[CHAR_BIT]; - - for (byte bit = 0; bit < CHAR_BIT; bit++) { - if (get_chance(probability) && (damage_left > 0)) { - bit_mask[bit] = true; - damage_left--; - } else { - bit_mask[bit] = false; - } - } - - bool damaged_byte = false; - - for (byte bit = 0; bit < threshold; bit++) { - if (bit_mask[bit] == false) - continue; - - byte_value = FLIP_BIT(byte_value, bit); - result->hit_counter++; - - damaged_byte = true; - - // write the modified byte back to the file - FSEEK_MACRO(file, i, SEEK_SET); - - if (fwrite(&byte_value, sizeof(byte), 1, file) == 1) - continue; - - // on error - result->error = true; - fclose(file); - return result; - } - - if (damaged_byte) - result->damaged_bytes++; - } + for (file_offset_t i = start; i < end; i++) + CORRUPT_BYTE_MACRO; puts(" [OK]"); }