Skip to content

Commit 3ed2ba6

Browse files
committed
use constants
1 parent 5b000cf commit 3ed2ba6

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

program/src/processor.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@ use {
1212
std::collections::BTreeSet,
1313
};
1414

15+
// Maximum input buffer length that can be deserialized.
16+
// See `solana_sdk::packet::PACKET_DATA_SIZE`.
17+
const MAX_INPUT_LEN: usize = 1232;
18+
// Maximum vector length for a `ConfigKeys` struct's `keys` list.
19+
// See comments below for `safe_deserialize_config_keys`.
20+
//
21+
// Take the maximum input length and subtract (up to) 3 bytes for the
22+
// `ShortU16`, then divide that by the size of a `(Pubkey, bool)` entry.
23+
const MAX_VECTOR_LEN: usize = (MAX_INPUT_LEN - 3) / (32 + 1);
24+
1525
// [Core BPF]: The original Config builtin leverages the
1626
// `solana_sdk::program_utils::limited_deserialize` method to cap the length of
17-
// the input buffer at 1232 (`solana_sdk::packet::PACKET_DATA_SIZE`). As a
18-
// result, any input buffer larger than 1232 will abort deserialization and
19-
// return `InstructionError::InvalidInstructionData`.
27+
// the input buffer at `MAX_INPUT_LEN` (1232). As a result, any input buffer
28+
// larger than `MAX_INPUT_LEN` will abort deserialization and return
29+
// `InstructionError::InvalidInstructionData`.
2030
//
2131
// Howevever, since `ConfigKeys` contains a vector of `(Pubkey, bool)`, the
2232
// `limited_deserialize` method will still read the vector's length and attempt
@@ -26,19 +36,15 @@ use {
2636
//
2737
// To mitigate this memory issue, the BPF version of the Config program has
2838
// been designed to "peek" the length value, and ensure it cannot allocate a
29-
// vector that would otherwise violate the input buffer length restriction of
30-
// 1232.
31-
//
32-
// Taking the maximum input length of 1232 and subtracting (up to) 3 bytes for
33-
// the `ShortU16`, then dividing that by the size of a `(Pubkey, bool)` entry
34-
// (33), we get a maximum vector size of 37. A `ShortU16` value for 37 fits in
35-
// just one byte (`[0x25]`), so this function can simply check the first
36-
// provided byte.
39+
// vector that would otherwise violate the input buffer length restriction.
40+
// Since a `ShortU16` value for `MAX_VECTOR_LEN` fits in just one byte, we can
41+
// simply peek the first byte before attempting deserialization.
3742
fn safe_deserialize_config_keys(input: &[u8]) -> Result<ConfigKeys, ProgramError> {
3843
match input.first() {
39-
Some(first_byte) if *first_byte <= 0x25 => {
44+
Some(first_byte) if *first_byte as usize <= MAX_VECTOR_LEN => {
4045
solana_program::program_utils::limited_deserialize::<ConfigKeys>(
41-
input, 1232, // [Core BPF]: See `solana_sdk::packet::PACKET_DATA_SIZE`
46+
input,
47+
MAX_INPUT_LEN as u64,
4248
)
4349
.map_err(|_| ProgramError::InvalidInstructionData)
4450
}

0 commit comments

Comments
 (0)