Skip to content

Commit

Permalink
Merge pull request #32 from thetacom/28-indexerror-bytearray-index-ou…
Browse files Browse the repository at this point in the history
…t-of-range-when-appending-to-file

28 indexerror bytearray index out of range when appending to file
  • Loading branch information
thetacom authored Mar 16, 2024
2 parents b96051f + ff7c680 commit 776158a
Show file tree
Hide file tree
Showing 7 changed files with 937 additions and 904 deletions.
5 changes: 4 additions & 1 deletion hexabyte/actions/api/set.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,11 @@ def do(self) -> None:
if self.target is None:
raise ActionError("Action target not set.")
api = self.target
if self.offset.byte == api.cursor.max_bytes:
api.cursor.max_bytes += 1
api.seek(self.offset.byte)
self.previous_value = unpack("@B", api.read(1))[0]
current_data = api.read(1)
self.previous_value = unpack("@B", current_data)[0] if current_data else 0
if self.offset_type == OffsetType.BIT:
bit_position = self.offset.remainder_bits
if self.value == 0:
Expand Down
12 changes: 11 additions & 1 deletion hexabyte/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def __init__(self, val: int = 0, max_bytes: int = 0) -> None:
"""Initialize Cursor."""
super().__init__()
self._absolute = val
self._max = max_bytes * BYTE_BITS
self.max_bytes = max_bytes

@property
def bit(self) -> int:
Expand Down Expand Up @@ -77,6 +77,16 @@ def dword64(self, byte_offset: int) -> None:
"""
self.byte = byte_offset >> DWORD64_ALIGN_BITS << DWORD64_ALIGN_BITS

@property
def max_bytes(self) -> int:
"""Return the max bytes allowed by cursor."""
return self._max // BYTE_BITS

@max_bytes.setter
def max_bytes(self, max_bytes: int) -> None:
"""Set the max byte value for cursor."""
self._max = max_bytes * BYTE_BITS

@property
def nibble(self) -> int:
"""Return the nibble aligned cursor position as bit offset."""
Expand Down
22 changes: 19 additions & 3 deletions hexabyte/view_components/byte_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ def generate_text(self, offset: int, data: bytes, highlights: list[DataSegment])
text = self._generate_hex_text(offset, data, highlights)
if self.view_mode is DisplayMode.UTF8:
text = self._generate_utf8_text(offset, data, highlights)
if (
self.cursor_visible
and self.cursor is not None
and self.cursor.byte >= offset + len(data)
and self.cursor.byte < offset + self.line_byte_length
):
text.append(Text(" ", self.cursor_style))
return text

def _generate_bin_text(self, offset: int, data: bytes, highlights: list[DataSegment]) -> Text:
Expand All @@ -195,6 +202,8 @@ def _generate_bin_text(self, offset: int, data: bytes, highlights: list[DataSegm
byte_position = offset
for col_start in range(0, self.line_byte_length, self.column_size):
chunk = data[col_start : col_start + self.column_size]
if not chunk:
break
for bite in chunk:
if bite == 0:
txt = Text("00000000", self.text_style)
Expand All @@ -211,7 +220,8 @@ def _generate_bin_text(self, offset: int, data: bytes, highlights: list[DataSegm
txt.stylize(self.highlight_style)
text.append(txt)
byte_position += 1
text.append(" ")
if self.line_byte_length != self.column_size:
text.append(" ")
return text

def _generate_hex_text(self, offset: int, data: bytes, highlights: list[DataSegment]) -> Text:
Expand All @@ -220,6 +230,8 @@ def _generate_hex_text(self, offset: int, data: bytes, highlights: list[DataSegm
byte_position = offset
for col_start in range(0, self.line_byte_length, self.column_size):
chunk = data[col_start : col_start + self.column_size]
if not chunk:
break
for bite in chunk:
if bite == 0:
txt = Text("00", self.text_style)
Expand All @@ -237,7 +249,8 @@ def _generate_hex_text(self, offset: int, data: bytes, highlights: list[DataSegm
txt.stylize(self.highlight_style)
text.append(txt)
byte_position += 1
text.append(" ")
if self.line_byte_length != self.column_size:
text.append(" ")
return text

def _generate_utf8_text(self, offset: int, data: bytes, highlights: list[DataSegment]) -> Text:
Expand All @@ -246,6 +259,8 @@ def _generate_utf8_text(self, offset: int, data: bytes, highlights: list[DataSeg
byte_position = offset
for col_start in range(0, self.line_byte_length, self.column_size):
chunk = data[col_start : col_start + self.column_size]
if not chunk:
break
for bite in chunk:
if not chr(bite).isprintable():
txt = Text(".", self.text_style)
Expand All @@ -262,7 +277,8 @@ def _generate_utf8_text(self, offset: int, data: bytes, highlights: list[DataSeg
txt.stylize(self.highlight_style)
text.append(txt)
byte_position += 1
text.append(" ")
if self.line_byte_length != self.column_size:
text.append(" ")
return text

def _get_view(
Expand Down
5 changes: 3 additions & 2 deletions hexabyte/widgets/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def __init__(
@property
def _cursor_at_end(self) -> bool:
"""Flag to indicate if the cursor is at the end."""
return self.cursor >= len(self.api) * BYTE_BITS
return self.cursor > self.api.cursor.max_bytes

@property
def _cursor_y(self) -> int:
Expand Down Expand Up @@ -288,7 +288,8 @@ def insert_at_cursor(self, char: str) -> None:
# if text not in ByteView.VALID_CHARS[self.display_mode]:
# raise ValueError("Invalid Character")
self.api.cursor.bit = self.cursor
current_value = self.api.read_at(self.api.cursor.byte, 1)[0]
current_data = self.api.read_at(self.api.cursor.byte, 1)
current_value = current_data[0] if current_data else 0
if self.display_mode == DisplayMode.HEX:
nibble = self.api.cursor.remainder_bits // NIBBLE_BITS
cmd = f"set nibble {self.api.cursor.byte} {nibble} 0x{char}"
Expand Down
Loading

0 comments on commit 776158a

Please sign in to comment.