Skip to content

Commit 6be72e6

Browse files
committed
Use read_unaligned when reading u64
Casting an arbitrary pointer to `u64` is an undefined behavior. Not sure if casting of the discriminator value is really necessary, as it is just a `u8` in this example. But using the same `*ptr.cast::<uXX>()` pattern in there seems wrong. It is a noop for `u8`, but if a `u64` is used, it becomes undefined behavior as well. Also, the `unsafe` usage is somewhat unclear. Dereferencing a pointer is an unsafe operation, but the first two examples do not have `unsafe`. Yet in the last example, when a slice is constructed, `unsafe` is present. I assume that the first two examples are expected to be in an unsafe context already?
1 parent 12601c9 commit 6be72e6

1 file changed

Lines changed: 7 additions & 7 deletions

File tree

  • src/app/content/courses/pinocchio-for-dummies/middleware-entrypoint

src/app/content/courses/pinocchio-for-dummies/middleware-entrypoint/en.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ Always verify that account offsets and lengths match expectations. Use [sbpf.xyz
124124

125125
```rust
126126
if *input == 4
127-
&& (*input.add(ACCOUNT1_DATA_LEN).cast::<u64>() == 165)
128-
&& (*input.add(ACCOUNT2_DATA_LEN).cast::<u64>() == 82)
129-
&& (*input.add(IX12_ACCOUNT3_DATA_LEN).cast::<u64>() == 165)
127+
&& (input.add(ACCOUNT1_DATA_LEN).cast::<u64>().read_unaligned() == 165)
128+
&& (input.add(ACCOUNT2_DATA_LEN).cast::<u64>().read_unaligned() == 82)
129+
&& (input.add(IX12_ACCOUNT3_DATA_LEN).cast::<u64>().read_unaligned() == 165)
130130
{
131131
//...
132132
}
@@ -145,16 +145,16 @@ fn align(input: u64) -> u64 {
145145

146146
// The `authority` account can have variable data length.
147147
let account_4_data_len_aligned =
148-
align(*input.add(IX12_ACCOUNT4_DATA_LEN).cast::<u64>()) as usize;
148+
align(input.add(IX12_ACCOUNT4_DATA_LEN).cast::<u64>().read_unaligned()) as usize;
149149
let offset = IX12_EXPECTED_INSTRUCTION_DATA_LEN_OFFSET + account_4_data_len_aligned;
150150
```
151151

152152
Once validation passes, extract instruction data, transmute accounts, and process normally:
153153

154154
```rust
155155
// Check that we have enough instruction data.
156-
if input.add(offset).cast::<usize>().read() >= INSTRUCTION_DATA_SIZE {
157-
let discriminator = input.add(offset + size_of::<u64>()).cast::<u8>().read();
156+
if unsafe { input.add(offset).cast::<usize>().read_unaligned() } >= INSTRUCTION_DATA_SIZE {
157+
let discriminator = unsafe { input.add(offset + size_of::<u64>()).cast::<u8>().read() };
158158

159159
// Check for instruction discriminator.
160160
if likely(discriminator == 12) {
@@ -179,4 +179,4 @@ if input.add(offset).cast::<usize>().read() >= INSTRUCTION_DATA_SIZE {
179179
};
180180
}
181181
}
182-
```
182+
```

0 commit comments

Comments
 (0)