1
0
mirror of https://git.disroot.org/80486DX2-66/polonium.git synced 2024-12-26 15:10:40 +05:30

corrupter.c: extract corrupt_byte

This commit is contained in:
Intel A80486DX2-66 2024-11-19 21:03:33 +03:00
parent 7f6a63232f
commit 82fdb03c4c
Signed by: 80486DX2-66
GPG Key ID: 83631EF27054609B

View File

@ -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]");
}