Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions program/src/processor/set_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,19 @@ pub fn set_data(accounts: &mut [AccountView], instruction_data: &[u8]) -> Progra
validate_authority(header, authority, program, program_data)?;
}

let has_buffer = buffer.address() != &crate::ID;
// Get data from buffer or remaining instruction data, if any.
let data = match (optional_data, has_buffer) {
// buffer (if `remaining_data` is `None`)
// - must be initialized
// - must be owned by the program
//
// Get data from buffer or remaining instruction data (if any).
let data = match (optional_data, buffer.address() != &crate::ID) {
(Some((data_source, Some(remaining_data))), false) => Some((data_source, remaining_data)),
(Some((data_source, None)), true) => {
// Since we are not writing to the `buffer` account, validate
// the ownership of the account.
if !buffer.owned_by(&crate::ID) {
return Err(ProgramError::InvalidAccountOwner);
}
// SAFETY: single immutable borrow of `buffer` account data.
let buffer_data = unsafe { buffer.borrow_unchecked() };

Expand Down
15 changes: 14 additions & 1 deletion program/src/processor/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ pub fn write(accounts: &mut [AccountView], instruction_data: &[u8]) -> ProgramRe
// - must be initialized
// - must be rent exempt (pre-funded account) since we are reallocating the buffer
// account
//
// source_buffer (if `args.data()` is empty)
// - must be initialized
// - must be owned by the program
// - must not be the same account as `target_buffer`

let (required_length, source_data) = {
// SAFETY: scoped immutable borrow of `buffer` account data. There
Expand All @@ -62,6 +67,11 @@ pub fn write(accounts: &mut [AccountView], instruction_data: &[u8]) -> ProgramRe
};

let source_buffer_data = if source_buffer.address() != &crate::ID {
// Since we are not writing to the `source_buffer` account, validate
// the ownership of the account.
if !source_buffer.owned_by(&crate::ID) {
return Err(ProgramError::InvalidAccountOwner);
}
// SAFETY: singe immutable borrow of `source_buffer` account data.
Some(unsafe { source_buffer.borrow_unchecked() })
} else {
Expand All @@ -71,7 +81,10 @@ pub fn write(accounts: &mut [AccountView], instruction_data: &[u8]) -> ProgramRe
let source_data = match (instruction_data, source_buffer_data) {
(Some(instruction_data), None) => instruction_data,
(None, Some(buffer_data)) => match AccountDiscriminator::try_from_bytes(buffer_data)? {
Some(AccountDiscriminator::Buffer) => &buffer_data[Header::LEN..],
// `source_buffer` and `target_buffer` must not be the same account.
Some(AccountDiscriminator::Buffer) if source_buffer != target_buffer => {
&buffer_data[Header::LEN..]
}
_ => return Err(ProgramError::InvalidAccountData),
},
_ => return Err(ProgramError::InvalidInstructionData),
Expand Down
Loading