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:
parent
7f6a63232f
commit
82fdb03c4c
135
src/corrupter.c
135
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]");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user