Skip to content

Commit

Permalink
Implement multibyte wb support
Browse files Browse the repository at this point in the history
  • Loading branch information
jukuisma committed Oct 6, 2024
1 parent 99d63a6 commit 3a4e307
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 17 deletions.
84 changes: 69 additions & 15 deletions libr/core/cmd_write.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2155,22 +2155,76 @@ static int cmd_wa(void *data, const char *input) {

static int cmd_wb(void *data, const char *input) {
RCore *core = (RCore *)data;
ut8 b = core->block[0];
char *ui = r_str_newf ("%sb", r_str_trim_head_ro (input));
int uil = strlen (ui) - 1;
int n = r_num_get (NULL, ui);
free (ui);
if (uil > 8) {
R_LOG_ERROR ("wb only operates on bytes");
} else if (uil > 0) {
// Shift left and right to zero uil most significant bits
b <<= uil;
b >>= uil;
// Overwrite uil most significant bits and keep the rest
b |= (n << (8 - uil));
r_io_write_at (core->io, core->offset, &b, 1);
} else {
int uil = strlen (input);
char c;
int i;

// Check that user provided some input
if (uil == 0) {
r_core_cmd_help_match (core, help_msg_w, "wb");
return 0;
}

// Check that user input only contains binary data
for (i = 0; i < uil; i++) {
c = input[i];
// Ignore whitespaces, \r and \n chars
if (c == ' ' || c == '\r' || c == '\n') {
continue;
}
// Check that user input only contains ones and zeros
else if (c != '0' && c != '1') {
R_LOG_ERROR ("wb only operates only on binary data");
return 0;
}
}

// Iterate user input bitwise and write output every 8 bits
int bits_read = 0;
int block_offset = 0;
ut8 byte = 0;
for (i = 0; i < uil; i++) {
// Read a bit
c = input[i];

// Ignore whitespaces, \r and \n chars
if (c == ' ' || c == '\r' || c == '\n') {
continue;
}

if (c == '1') {
// Bits are read and bytes constructed from most to
// least significant.
byte |= (1 << (7 - bits_read));
}
bits_read++;

// Write a byte if we've read 8 bits
if (bits_read % 8 == 0) {
r_io_write_at (
core->io,
// TODO: Do we need some bound check for
// `core->offset + block_offset`? Other
// functions don't seem to implement any.
core->offset + block_offset,
&byte,
1
);
block_offset++;
bits_read = 0;
byte = 0;
}
}

// Write any possible remaining ui bits
if (bits_read != 0) {
ut8 b = core->block[block_offset];
// Shift left and right to zero bits_read most significant bits
b <<= bits_read;
b >>= bits_read;
// Overwrite bits_read most significant bits and keep the rest
b |= byte;
r_io_write_at (core->io, core->offset + block_offset, &b, 1);
}

return 0;
Expand Down
4 changes: 2 additions & 2 deletions test/db/cmd/cmd_print_bitformat
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ wb 1111111111111111111111111111
pb 28
wb 1010101010101010101010101010
pb 28
wb 000 @ 3
wb 0 @ 3
pb 28
EOF
EXPECT=<<EOF
0000000000000000000000000000
1111111111111111111111111111
1010101010101010101010101010
1010101010101010101000001010
1010101010101010101010100010
EOF
RUN

0 comments on commit 3a4e307

Please sign in to comment.