Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(chat): metadata panic #6247

Merged
merged 7 commits into from
Apr 10, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 27 additions & 29 deletions base_layer/chat_ffi/chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,14 @@ struct ChatByteVector *read_confirmation_message_id(struct Confirmation *confirm
int *error_out);

/**
* Get a c_longlong timestamp for the Confirmation
* Get a c_ulonglong timestamp for the Confirmation
*
* ## Arguments
* `confirmation` - A pointer to the Confirmation
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_longlong` - A uint representation of time since epoch
* `c_ulonglong` - A uint representation of time since epoch. May return 0 on error
*
* # Safety
* The ```confirmation``` When done with the Confirmation it should be destroyed
Expand Down Expand Up @@ -329,7 +329,7 @@ void add_chat_contact(struct ChatClient *client, struct TariAddress *address, in
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `status` - Returns an int representing of the online status
* `status` - Returns an c_uchar representing of the online status
* Online = 1,
* Offline = 2,
* NeverSeen = 3,
Expand All @@ -338,7 +338,9 @@ void add_chat_contact(struct ChatClient *client, struct TariAddress *address, in
* # Safety
* The ```address``` should be destroyed after use
*/
int check_online_status(struct ChatClient *client, struct TariAddress *receiver, int *error_out);
unsigned char check_online_status(struct ChatClient *client,
struct TariAddress *receiver,
int *error_out);

/**
* Returns a pointer to a TariAddress
Expand Down Expand Up @@ -385,14 +387,14 @@ unsigned char read_liveness_data_online_status(struct ContactsLivenessData *live
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_longlong` - A c_longlong rep of an enum for a contacts online status. May return -1 if an error
* occurs, or 0 if the contact has never been seen
* `c_ulonglong` - A c_longlong rep of timestamp for a contacts last seen status.
* 0 if the contact has never been seen or an error occurs.
*
* ## Safety
* `liveness` should be destroyed eventually
*/
long long read_liveness_data_last_seen(struct ContactsLivenessData *liveness,
int *error_out);
unsigned long long read_liveness_data_last_seen(struct ContactsLivenessData *liveness,
int *error_out);

/**
* Frees memory for a ContactsLivenessData
Expand Down Expand Up @@ -431,13 +433,13 @@ struct ConversationalistsVector *get_conversationalists(struct ChatClient *clien
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_int` - The length of the vector. May return -1 if something goes wrong
* `c_uint` - The length of the vector. May return 0 if something goes wrong
*
* ## Safety
* `conversationalists` should be destroyed eventually
*/
int conversationalists_vector_len(struct ConversationalistsVector *conversationalists,
int *error_out);
unsigned int conversationalists_vector_len(struct ConversationalistsVector *conversationalists,
int *error_out);

/**
* Reads the ConversationalistsVector and returns a pointer to a TariAddress at a given position
Expand Down Expand Up @@ -548,13 +550,12 @@ struct MessageMetadata *chat_metadata_get_at(struct Message *message,
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_longlong` - The length of the metadata vector for a Message. May return -1 if something goes wrong
* `c_uint` - The length of the metadata vector for a Message. May return 0 if something goes wrong
*
* ## Safety
* `message` should be destroyed eventually
*/
long long chat_message_metadata_len(struct Message *message,
int *error_out);
unsigned int chat_message_metadata_len(struct Message *message, int *error_out);

/**
* Returns a pointer to a ChatByteVector representing the data of the Message
Expand Down Expand Up @@ -589,21 +590,21 @@ struct ChatByteVector *read_chat_message_body(struct Message *message, int *erro
struct TariAddress *read_chat_message_address(struct Message *message, int *error_out);

/**
* Returns a c_int representation of the Direction enum
* Returns a c_uchar representation of the Direction enum
*
* ## Arguments
* `message` - A pointer to a Message
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_int` - A c_int rep of the direction enum. May return -1 if anything goes wrong
* `c_uchar` - A c_uchar rep of the direction enum. May return 0 if anything goes wrong
* 0 => Inbound
* 1 => Outbound
*
* ## Safety
* `message` should be destroyed eventually
*/
int read_chat_message_direction(struct Message *message, int *error_out);
unsigned char read_chat_message_direction(struct Message *message, int *error_out);

/**
* Returns a c_ulonglong representation of the stored at timestamp as seconds since epoch
Expand Down Expand Up @@ -674,9 +675,7 @@ struct ChatByteVector *read_chat_message_id(struct Message *message, int *error_
*
* ## Arguments
* `message` - A pointer to a message
* `metadata_type` - An c_uchar that maps to MessageMetadataType enum
* '0' -> Reply
* '1' -> TokenRequest
* `key` - A pointer to a byte vector containing bytes for the key field
* `data` - A pointer to a byte vector containing bytes for the data field
* `error_out` - Pointer to an int which will be modified
*
Expand All @@ -687,7 +686,7 @@ struct ChatByteVector *read_chat_message_id(struct Message *message, int *error_
* `message` should be destroyed eventually
*/
void add_chat_message_metadata(struct Message *message,
unsigned char metadata_type,
struct ChatByteVector *key,
struct ChatByteVector *data,
int *error_out);

Expand All @@ -699,14 +698,13 @@ void add_chat_message_metadata(struct Message *message,
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_int` - An int8 that maps to MessageMetadataType enum. May return -1 if something goes wrong
* '0' -> Reply
* '1' -> TokenRequest
* `*mut ChatByteVector` - A ptr to a ChatByteVector
*
* ## Safety
* `msg_metadata` should be destroyed eventually
* the returned `ChatByteVector` should be destroyed eventually
*/
int read_chat_metadata_type(struct MessageMetadata *msg_metadata, int *error_out);
struct ChatByteVector *read_chat_metadata_key(struct MessageMetadata *msg_metadata, int *error_out);

/**
* Returns a ptr to a ByteVector
Expand Down Expand Up @@ -759,8 +757,8 @@ void destroy_chat_message_metadata(struct MessageMetadata *ptr);
*/
struct MessageVector *get_chat_messages(struct ChatClient *client,
struct TariAddress *address,
int limit,
int page,
unsigned int limit,
unsigned int page,
int *error_out);

/**
Expand All @@ -771,12 +769,12 @@ struct MessageVector *get_chat_messages(struct ChatClient *client,
* `error_out` - Pointer to an int which will be modified
*
* ## Returns
* `c_int` - The length of the metadata vector for a Message. May return -1 if something goes wrong
* `c_uint` - The length of the metadata vector for a Message. May return 0 if something goes wrong
*
* ## Safety
* `messages` should be destroyed eventually
*/
int message_vector_len(struct MessageVector *messages, int *error_out);
unsigned int message_vector_len(struct MessageVector *messages, int *error_out);

/**
* Reads the MessageVector and returns a Message at a given position
Expand Down
14 changes: 14 additions & 0 deletions base_layer/chat_ffi/src/byte_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,17 @@ pub unsafe extern "C" fn chat_byte_vector_get_length(vec: *const ChatByteVector,

(*vec).0.len() as c_uint
}

pub(crate) unsafe fn process_vector(vector: *mut ChatByteVector, error_out: *mut c_int) -> Vec<u8> {
let data_byte_vector_length = chat_byte_vector_get_length(vector, error_out);
let mut bytes: Vec<u8> = Vec::new();

if data_byte_vector_length > 0 {
for c in 0..data_byte_vector_length {
let byte = chat_byte_vector_get_at(vector, c as c_uint, error_out);
bytes.push(byte);
}
}

bytes
}
15 changes: 12 additions & 3 deletions base_layer/chat_ffi/src/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,27 @@ pub unsafe extern "C" fn read_confirmation_message_id(

let c = &(*confirmation);
let data_bytes = c.message_id.clone();
let len = u32::try_from(data_bytes.len()).expect("Can't cast from usize");

let len = match u32::try_from(data_bytes.len()) {
Ok(l) => l,
Err(e) => {
error = LibChatError::from(InterfaceError::ConversionError(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
0
},
};

chat_byte_vector_create(data_bytes.as_ptr(), len as c_uint, error_out)
}

/// Get a c_longlong timestamp for the Confirmation
/// Get a c_ulonglong timestamp for the Confirmation
///
/// ## Arguments
/// `confirmation` - A pointer to the Confirmation
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `c_longlong` - A uint representation of time since epoch
/// `c_ulonglong` - A uint representation of time since epoch. May return 0 on error
///
/// # Safety
/// The ```confirmation``` When done with the Confirmation it should be destroyed
Expand Down
8 changes: 4 additions & 4 deletions base_layer/chat_ffi/src/contacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

use std::ptr;

use libc::c_int;
use libc::{c_int, c_uchar};
use tari_chat_client::ChatClient as ChatClientTrait;
use tari_common_types::tari_address::TariAddress;

Expand Down Expand Up @@ -74,7 +74,7 @@ pub unsafe extern "C" fn add_chat_contact(client: *mut ChatClient, address: *mut
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `status` - Returns an int representing of the online status
/// `status` - Returns an c_uchar representing of the online status
/// Online = 1,
/// Offline = 2,
/// NeverSeen = 3,
Expand All @@ -87,7 +87,7 @@ pub unsafe extern "C" fn check_online_status(
client: *mut ChatClient,
receiver: *mut TariAddress,
error_out: *mut c_int,
) -> c_int {
) -> c_uchar {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

Expand All @@ -105,7 +105,7 @@ pub unsafe extern "C" fn check_online_status(
let result = (*client).runtime.block_on((*client).client.check_online_status(&rec));

match result {
Ok(status) => status.as_u8().into(),
Ok(status) => status.as_u8(),
Err(e) => {
error = LibChatError::from(InterfaceError::ContactServiceError(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
Expand Down
18 changes: 12 additions & 6 deletions base_layer/chat_ffi/src/contacts_liveness_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use std::ptr;
use std::{convert::TryFrom, ptr};

use libc::{c_int, c_longlong, c_uchar};
use libc::{c_int, c_uchar, c_ulonglong};
use tari_common_types::tari_address::TariAddress;
use tari_contacts::contacts_service::handle::ContactsLivenessData;

Expand Down Expand Up @@ -97,16 +97,16 @@ pub unsafe extern "C" fn read_liveness_data_online_status(
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `c_longlong` - A c_longlong rep of an enum for a contacts online status. May return -1 if an error
/// occurs, or 0 if the contact has never been seen
/// `c_ulonglong` - A c_longlong rep of timestamp for a contacts last seen status.
/// 0 if the contact has never been seen or an error occurs.
///
/// ## Safety
/// `liveness` should be destroyed eventually
#[no_mangle]
pub unsafe extern "C" fn read_liveness_data_last_seen(
liveness: *mut ContactsLivenessData,
error_out: *mut c_int,
) -> c_longlong {
) -> c_ulonglong {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

Expand All @@ -117,7 +117,13 @@ pub unsafe extern "C" fn read_liveness_data_last_seen(
}

match (*liveness).last_ping_pong_received() {
Some(last_seen) => last_seen.timestamp(),
Some(last_seen) => match u64::try_from(last_seen.timestamp()) {
Ok(ls) => ls as c_ulonglong,
Err(_e) => {
ptr::swap(error_out, &mut error as *mut c_int);
0
},
},
None => 0,
}
}
Expand Down
15 changes: 11 additions & 4 deletions base_layer/chat_ffi/src/conversationalists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,33 @@ pub unsafe extern "C" fn get_conversationalists(
/// `error_out` - Pointer to an int which will be modified
///
/// ## Returns
/// `c_int` - The length of the vector. May return -1 if something goes wrong
/// `c_uint` - The length of the vector. May return 0 if something goes wrong
///
/// ## Safety
/// `conversationalists` should be destroyed eventually
#[no_mangle]
pub unsafe extern "C" fn conversationalists_vector_len(
conversationalists: *mut ConversationalistsVector,
error_out: *mut c_int,
) -> c_int {
) -> c_uint {
let mut error = 0;
ptr::swap(error_out, &mut error as *mut c_int);

if conversationalists.is_null() {
error = LibChatError::from(InterfaceError::NullError("conversationalists".to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
return -1;
return 0;
}

let conversationalists = &(*conversationalists);
c_int::try_from(conversationalists.0.len()).unwrap_or(-1)
match c_uint::try_from(conversationalists.0.len()) {
Ok(l) => l,
Err(e) => {
error = LibChatError::from(InterfaceError::ConversionError(e.to_string())).code;
ptr::swap(error_out, &mut error as *mut c_int);
0
},
}
}

/// Reads the ConversationalistsVector and returns a pointer to a TariAddress at a given position
Expand Down
6 changes: 6 additions & 0 deletions base_layer/chat_ffi/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pub enum InterfaceError {
AllocationError,
#[error("An error because the supplied position was out of range")]
PositionInvalidError,
#[error("Conversion error: `{0}`")]
ConversionError(String),
#[error("The client had an error communication with contact services")]
ContactServiceError(String),
}
Expand Down Expand Up @@ -76,6 +78,10 @@ impl From<InterfaceError> for LibChatError {
code: 8,
message: format!("{:?}", v),
},
InterfaceError::ConversionError(_) => Self {
code: 9,
message: format!("{:?}", v),
},
}
}
}