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

change type of dc_msg_t.text to String #283

Merged
merged 3 commits into from
Aug 7, 2019
Merged

Conversation

KAction
Copy link

@KAction KAction commented Aug 3, 2019

Also, remove `send-garbage' command from REPL, since it is not possible to send
non-utf8 string anymore.

src/dc_chat.rs Outdated
@@ -1001,7 +991,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
// save new draft
if !msg.is_null() {
if (*msg).type_0 == Viewtype::Text {
if (*msg).text.is_null() || *(*msg).text.offset(0isize) as libc::c_int == 0i32 {
if (*msg).text.is_none() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You change the logic here. Existing code checks for

(*msg).text.is_none() || (*msg).text.unwrap().is_empty()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KAction If I remember correctly you added the check for empty string but removed it now?

src/dc_mimefactory.rs Outdated Show resolved Hide resolved
src/dc_msg.rs Outdated
@@ -827,13 +834,21 @@ pub unsafe fn dc_msg_get_summarytext(
return dc_strdup(0 as *const libc::c_char);
}

dc_msg_get_summarytext_by_raw(
let msgtext_ptr = if let Some(ref text) = (*msg).text {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use map_or here.

src/dc_msg.rs Outdated
@@ -1049,8 +1064,7 @@ pub unsafe fn dc_msg_set_text(mut msg: *mut dc_msg_t, text: *const libc::c_char)
if msg.is_null() || (*msg).magic != 0x11561156i32 as libc::c_uint {
return;
}
free((*msg).text as *mut libc::c_void);
(*msg).text = dc_strdup(text);
(*msg).text = if text.is_null() { None } else { Some(to_string(text)) };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map_or

@KAction KAction force-pushed the msg-text branch 2 times, most recently from 6dcc8d8 to 35c2daa Compare August 3, 2019 17:07
src/dc_chat.rs Outdated
if (*msg).text.is_null() || *(*msg).text.offset(0isize) as libc::c_int == 0i32 {
OK_TO_CONTINUE = false;
OK_TO_CONTINUE = match (*msg).text {
None => false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use .map_or here as well?

@link2xt
Copy link
Collaborator

link2xt commented Aug 3, 2019

I am ok with merging as-is after cargo fmt.

All those map_or suggestions are a matter of taste.

@KAction KAction changed the title Change type of dc_msg_t.text to String WIP: change type of dc_msg_t.text to String Aug 3, 2019
@KAction
Copy link
Author

KAction commented Aug 3, 2019

Okay. Plus-control passed. Master builds fine.

@KAction
Copy link
Author

KAction commented Aug 4, 2019

I am ok with merging as-is after cargo fmt.

All those map_or suggestions are a matter of taste.

@link2xt No. Somewhy it breaks tests. Investigating.

@KAction KAction force-pushed the msg-text branch 3 times, most recently from 2054cd0 to fb1622a Compare August 4, 2019 14:42
@KAction KAction changed the title WIP: change type of dc_msg_t.text to String change type of dc_msg_t.text to String Aug 4, 2019
@KAction
Copy link
Author

KAction commented Aug 4, 2019

I think it is ready. The catch was that Option<String> was passed to params!, and, I believe, translated to SQL NULL. It should have caused error somewhere, I think.

src/dc_chat.rs Outdated
if OK_TO_CONTINUE {
dbg!();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these dbg!s going to be useful later?

Copy link
Author

@KAction KAction Aug 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. This is bug. Just fixed.

src/dc_chat.rs Outdated
@@ -1001,7 +991,7 @@ unsafe fn set_draft_raw(context: &Context, chat_id: uint32_t, msg: *mut dc_msg_t
// save new draft
if !msg.is_null() {
if (*msg).type_0 == Viewtype::Text {
if (*msg).text.is_null() || *(*msg).text.offset(0isize) as libc::c_int == 0i32 {
if (*msg).text.is_none() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KAction If I remember correctly you added the check for empty string but removed it now?

Previous version of patch, that changed type of `dc_msg_t.text' to String had
been breaking `prepare_and_send' test in Python.

This commit adds same regression test, reimplemented in Rust, since running
Rust tests is simplier and faster.
src/dc_chat.rs Outdated
@@ -725,7 +725,7 @@ unsafe fn prepare_msg_raw(
timestamp,
(*msg).type_0,
(*msg).state,
if !(*msg).text.is_null() { Some(as_str((*msg).text)) } else { None },
(*msg).text.deref().unwrap_or(""),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dignifiedquire previously said that using unstable features is discouraged because the goal is to move to stable Rust. This seems to be the line that requires inner_deref.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay.


let res = dc_truncate_str(as_str((*msg).text), 30000);
res.strdup()
if let Some(ref text) = (*msg).text {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, code panic!'ed if msg.text is null. Now, this code returns NULL. Probably this is right thing to do.

On other hand, I think that check for msg.is_null() is wrong. Function should not silently fail on bogus input, it should panic, imho. I spent some time debugging, while dc_get_msg_id(NULL) == 0.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All those is_null checks are from the legacy C code. It accepted nulls everywhere and proceeded as if nothing happened instead of failing. That is in spirit of C, where free accepts NULL.

For Rust code, I am in favor of fail-fast design. Users of the library should avoid passing nulls where data is expected.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite off-topic, but I disagree that it is in spirit of C. free is exception, not rule. Most C API cause UB (e.g SIGSEGV) on NULL pointer: fopen, fprint, open, readdir, regcomp, ...

On rust code, good. Will add some asserts.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add some asserts.

Not in this PR, though. These changes need to be aligned with bindings/android/desktop/ios code, they may rely on this behavior.

@KAction KAction force-pushed the msg-text branch 2 times, most recently from 07d7d54 to 9ab922a Compare August 4, 2019 18:24
src/dc_msg.rs Outdated Show resolved Hide resolved
Dmitry Bogatov added 2 commits August 4, 2019 19:31
Also, remove `send-garbage' command from REPL, since it is not possible to send
non-utf8 string anymore.
} else {
""
},
(*msg).text.as_ref().map(String::as_str).unwrap_or(""),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.unwrap_or_default() would be the same? Not that I mind.

.text
.as_ref()
.map(|s| CString::yolo(String::as_str(s)));
let msgtext_ptr = msgtext_c.map_or(ptr::null(), |s| s.as_ptr());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, this is nice! I think there are a lot of places that simply do s.as_ptr() instead of the full .map_or(ptr::null(), |s| s.as_ptr()) and that's probably the cause of a bunch of crashes.

@@ -31,7 +32,7 @@ pub struct dc_msg_t<'a> {
pub timestamp_sort: i64,
pub timestamp_sent: i64,
pub timestamp_rcvd: i64,
pub text: *mut libc::c_char,
pub text: Option<String>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd kind of argue that this should be just be String and use "" if there is nothing. I think the None case is really an artefact of the C API and only needs to be replicated on that boundary layer. A lot of things probably become easier if you can just assume this is always a valid string instead of having to handle the Option.

I don't feel too strongly though, this PR is certainly already an improvement as is!

let contact = dc_create_contact(
ctx,
b"\x00".as_ptr().cast(),
b"dest@example.com\x00".as_ptr().cast(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also write this as "dest@example.com".strdup() I think (and above "".strdup()).

But TIL about .cast() though, nice.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strdup performs allocation, and must be freed manually. I'd rather have Rust do it for me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS. Since there is goal to drop unstable feature, cast will be gone eventually. Sad, I liked him.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KAction cast is stable now: rust-lang/rust#62713

@KAction
Copy link
Author

KAction commented Aug 7, 2019

Okay. What is missing for merging?

@link2xt
Copy link
Collaborator

link2xt commented Aug 7, 2019

@dignifiedquire has to change review to "approve"

@flub
Copy link
Member

flub commented Aug 7, 2019

Let's assume @dignifiedquire is busy and merge anyway. Things can always be changed later.

@flub flub merged commit bc23145 into deltachat:master Aug 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants