Skip to content

Commit 2a849b6

Browse files
committed
fix: CoPilot noticed a few smaller mistakes
1 parent baa56de commit 2a849b6

6 files changed

Lines changed: 29 additions & 12 deletions

File tree

docs/basics/pointers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ print(data.next.unwrap().value) # 99
4747

4848
### Safe Dereferencing
4949

50-
Use `try_unwrap()` for null-safe pointer access. It returns `None` if the pointer is null (0):
50+
Use `try_unwrap()` for safe pointer access. It returns `None` if the pointer address is unresolvable (e.g., out of bounds):
5151

5252
```python
5353
class node_t(struct):

docs/basics/types.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ memory = bytearray(b"Hello\x00World\x00")
123123
lib = inflater(memory)
124124

125125
s = lib.inflate(c_str, 0)
126-
print(s.value) # "Hello"
126+
print(s.value) # b"Hello"
127127
print(len(s)) # 5
128-
print(s[0]) # 72 (ord('H'))
128+
print(s[0]) # b"H"
129129
```
130130

131131
!!! info

docs/memory/resolvers.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ All resolvers implement these methods:
5151
|---|---|
5252
| `resolve(size, offset)` | Read `size` bytes starting at the resolved address + offset |
5353
| `resolve_address()` | Return the absolute address of this resolver |
54-
| `write(data)` | Write bytes at the resolved address |
54+
| `modify(size, index, value)` | Write `value` bytes at the resolved address + index |
5555
| `relative_from_own(offset, size)` | Create a child resolver at a relative offset |
5656
| `absolute_from_own(address)` | Create a child resolver at an absolute address |
5757

@@ -73,8 +73,8 @@ class DebuggerResolver(Resolver):
7373
def resolve_address(self):
7474
return self._address
7575

76-
def write(self, data, offset=0):
77-
self.debugger.write_memory(self._address + offset, data)
76+
def modify(self, size, index, value):
77+
self.debugger.write_memory(self._address + index, value)
7878

7979
# ... implement relative_from_own, absolute_from_own
8080
```

libdestruct/common/ptr/ptr.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ def __init__(self: ptr, resolver: Resolver, wrapper: type | None = None) -> None
5858
"""
5959
super().__init__(resolver)
6060
self.wrapper = wrapper
61-
self._cached_unwrap: obj | None = None
61+
self._cached_unwrap: obj | bytes | None = None
6262
self._cache_valid: bool = False
63+
self._cached_length: int | None = None
6364

6465
def get(self: ptr) -> int:
6566
"""Return the value of the pointer."""
@@ -82,14 +83,15 @@ def invalidate(self: ptr) -> None:
8283
"""Clear the cached unwrap result."""
8384
self._cached_unwrap = None
8485
self._cache_valid = False
86+
self._cached_length = None
8587

86-
def unwrap(self: ptr, length: int | None = None) -> obj:
88+
def unwrap(self: ptr, length: int | None = None) -> obj | bytes:
8789
"""Return the object pointed to by the pointer.
8890
8991
Args:
9092
length: The length of the object in memory this points to.
9193
"""
92-
if self._cache_valid:
94+
if self._cache_valid and self._cached_length == length:
9395
return self._cached_unwrap
9496

9597
address = self.get()
@@ -105,15 +107,16 @@ def unwrap(self: ptr, length: int | None = None) -> obj:
105107

106108
self._cached_unwrap = result
107109
self._cache_valid = True
110+
self._cached_length = length
108111
return result
109112

110-
def try_unwrap(self: ptr, length: int | None = None) -> obj | None:
113+
def try_unwrap(self: ptr, length: int | None = None) -> obj | bytes | None:
111114
"""Return the object pointed to by the pointer, if it is valid.
112115
113116
Args:
114117
length: The length of the object in memory this points to.
115118
"""
116-
if self._cache_valid:
119+
if self._cache_valid and self._cached_length == length:
117120
return self._cached_unwrap
118121

119122
address = self.get()

libdestruct/libdestruct.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
def inflater(memory: Sequence, endianness: str = "little") -> Inflater:
2020
"""Return a TypeInflater instance."""
2121
if not isinstance(memory, Sequence):
22-
raise TypeError(f"memory must be a MutableSequence, not {type(memory).__name__}")
22+
raise TypeError(f"memory must be a Sequence, not {type(memory).__name__}")
2323

2424
return Inflater(memory, endianness=endianness)
2525

test/scripts/types_unit_test.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,20 @@ def test_cache_invalidated_on_set(self):
293293
p.value = 12 # now points to offset 12
294294
self.assertEqual(p.unwrap().value, 20)
295295

296+
def test_untyped_cache_different_lengths(self):
297+
"""Untyped ptr cache must differentiate by length parameter."""
298+
memory = bytearray(8 + 4)
299+
memory[0:8] = (8).to_bytes(8, "little") # pointer to offset 8
300+
memory[8:12] = b"\x01\x02\x03\x04"
301+
302+
p = ptr(MemoryResolver(memory, 0))
303+
304+
r1 = p.unwrap(length=1)
305+
self.assertEqual(r1, b"\x01")
306+
307+
r2 = p.unwrap(length=3)
308+
self.assertEqual(r2, b"\x01\x02\x03")
309+
296310

297311
class FloatTest(unittest.TestCase):
298312
"""c_float and c_double types."""

0 commit comments

Comments
 (0)