WIP: copy proxy_host and savedata_data#909
Conversation
| Is removing |
| Why are you removing Reviewed 2 of 3 files at r1. toxcore/tox.h, line 625 at r1 (raw file):
Should be kept as const. toxcore/tox.h, line 692 at r1 (raw file):
This toxcore/tox.h, line 694 at r1 (raw file):
This toxcore/tox.api.h, line 565 at r1 (raw file):
This should remain const. toxcore/tox_api.c, line 66 at r1 (raw file):
toxcore/tox_api.c, line 79 at r1 (raw file):
Comments from Reviewable |
| Review status: 0 of 1 LGTMs obtained toxcore/tox.h, line 625 at r1 (raw file): Previously, nurupo wrote…
If I leave this const, I get the same error as here: https://travis-ci.org/TokTok/c-toxcore/builds/392474765#L1419 since toxcore/tox.h, line 692 at r1 (raw file): Previously, nurupo wrote…
This was not intentional, but I have no idea how to tell apidsl to make getters return a const pointer, even if the struct member is not const. toxcore/tox.h, line 694 at r1 (raw file): Previously, nurupo wrote…
same toxcore/tox.api.h, line 565 at r1 (raw file): Previously, nurupo wrote…
See the above issue with free toxcore/tox_api.c, line 66 at r1 (raw file): Previously, nurupo wrote…
agreed, but I think this breaks the API right? or at minimum the clients need to check additional things then toxcore/tox_api.c, line 79 at r1 (raw file): Previously, nurupo wrote…
same Comments from Reviewable |
| Review status: 0 of 1 LGTMs obtained toxcore/tox.h, line 625 at r1 (raw file): Previously, sudden6 wrote…
Oh, I see, this is the internal struct Comments from Reviewable |
| I think we should postponed this change until |
| I think now this is not possible without breaking the API and should be postponed until the next API break. Review status: 0 of 1 LGTMs obtained toxcore/tox.h, line 625 at r1 (raw file):
No, my intention was that Comments from Reviewable |
| This can now be completed because we got rid of apidsl. |
0237d8e to 531740e Compare | @iphydf updated, but I'm not sure how we should do the error handling in setters for malloc. I forgot to think about this in the last PR. I'm also not sure how the semantics of this function should be in case the user wants to unset the proxy. |
Why not just make it behave like the other API functions and set an error code? |
There was a problem hiding this comment.
Reviewed 3 of 3 files at r2.
Reviewable status: 0 of 1 approvals obtained (waiting on @nurupo and @sudden6)
toxcore/tox_api.c, line 80 at r2 (raw file):
void tox_options_set_proxy_host(struct Tox_Options *options, const char *host) { const size_t hostname_len = strlen(host);
Instead of calling strlen() maybe the caller could supply the length. toxcore doesn't generally deal with C strings.
toxcore/tox_api.c, line 102 at r2 (raw file):
{ options->savedata_data = (uint8_t *) malloc(length); if(!options->savedata_data) {
if (options->save_data == nullptr)
toxcore/tox_api.c, line 107 at r2 (raw file):
} memcpy(options->savedata_data, data, length);
Should we check that length is < sizeof(options->savedata_data) or just ask the caller to be sane?
toxcore/tox_api.c, line 145 at r2 (raw file):
free(options->proxy_host); } free(options);
Although there's nothing wrong with calling free on a null pointer, it seems weird to explicitly leave this outside of the if clause.
5d8d3af to ef5f181 Compare
sudden6 left a comment
There was a problem hiding this comment.
Reviewable status: 0 of 1 approvals obtained (waiting on @JFreegman and @nurupo)
toxcore/tox.h, line 692 at r1 (raw file):
Previously, sudden6 wrote…
This was not intentional, but I have no idea how to tell apidsl to make getters return a const pointer, even if the struct member is not const.
Done.
toxcore/tox.h, line 694 at r1 (raw file):
Previously, sudden6 wrote…
same
Done.
toxcore/tox_api.c, line 79 at r1 (raw file):
Previously, sudden6 wrote…
same
Added a boolean result parameter.
toxcore/tox_api.c, line 80 at r2 (raw file):
Previously, JFreegman wrote…
Instead of calling
strlen()maybe the caller could supply the length. toxcore doesn't generally deal with C strings.
Done. Kept a check for NUL termination though, AFAICT the string is used in places where it must be NUL terminated.
toxcore/tox_api.c, line 102 at r2 (raw file):
Previously, JFreegman wrote…
if (options->save_data == nullptr)
Done.
toxcore/tox_api.c, line 107 at r2 (raw file):
Previously, JFreegman wrote…
Should we check that length is < sizeof(options->savedata_data) or just ask the caller to be sane?
We just allocated it with the correct size though?
toxcore/tox_api.c, line 145 at r2 (raw file):
Previously, JFreegman wrote…
Although there's nothing wrong with calling free on a null pointer, it seems weird to explicitly leave this outside of the of this if clause.
IDK, I prefer to make as few things conditional as possible. Can change it though if that's a style requirement.
2891a35 to 481541a Compare 481541a to a83c2f5 Compare | toxcore/tox_api.c, line 107 at r2 (raw file): Previously, sudden6 wrote…
Ah yeah I misread that one |
a83c2f5 to 10e16eb Compare | toxcore/tox_api.c, line 145 at r2 (raw file): Previously, sudden6 wrote…
Just a style nitpick, either way is correct. |
65698ab to 5ee74fb Compare
nurupo left a comment
There was a problem hiding this comment.
Reviewed 9 of 10 files at r5.
Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @JFreegman, @nurupo, and @sudden6)
toxcore/tox_api.c, line 66 at r1 (raw file):
Previously, sudden6 wrote…
agreed, but I think this breaks the API right? or at minimum the clients need to check additional things then
You can add things to an enum without breaking ABI. Adding values at the very end of the enum is safe.
toxcore/tox_api.c, line 79 at r1 (raw file):
Previously, sudden6 wrote…
Added a boolean result parameter.
That's rather unusual. I'm going though the API and it looks like all functions that can return a failure (bool / null pointer, uin32_t) also have and error enum.
toxcore/tox_api.c, line 80 at r2 (raw file):
@JFreegman toxcore does deal with string hosts! How is this host argument in here any different from tox_bootstrap()'s host argument, which the documentation says/implies that must be null-terminated:
- @param host The hostname or IP address (IPv4 or IPv6) of the node. Must be
- at most TOX_MAX_HOSTNAME_LENGTH chars, including the NUL byte.
?
Ortox_add_tcp_relay()' host argument, which is the same.
Neither function accept a host_length argument.
sudden6 left a comment
There was a problem hiding this comment.
Reviewable status: 1 change requests, 0 of 1 approvals obtained (waiting on @JFreegman, @nurupo, and @sudden6)
toxcore/tox_api.c, line 80 at r2 (raw file):
Previously, nurupo wrote…
@JFreegman toxcore does deal with string hosts! How is this host argument in here any different from
tox_bootstrap()'s host argument, which the documentation says/implies that must be null-terminated:
- @param host The hostname or IP address (IPv4 or IPv6) of the node. Must be
- at most TOX_MAX_HOSTNAME_LENGTH chars, including the NUL byte.
?
Ortox_add_tcp_relay()' host argument, which is the same.
Neither function accept a host_length argument.
@nurupo you're right, and with some further thinking the current solution is worse than before, because now the string must be NUL terminated and length supplied. IMO for a sane API it should be either or and consistent with the rest of the API. So the decision is what style do we want for c-toxcore? Generally I'd see pointer+length as more sane than NUL terminated, but compatibility says otherwise.
toxcore/tox_api.c, line 107 at r2 (raw file):
Previously, JFreegman wrote…
Ah yeah I misread that one
Done.
toxcore/tox_api.c, line 145 at r2 (raw file):
Previously, JFreegman wrote…
Just a style nitpick, either way is correct.
Done.
| I've found a problem around IMO the @iphydf @JFreegman anything I missed that speaks against this? |
tox_options_new(...) already returns a default initialized options struct and this function makes it impossible to malloc buffers in Tox_Options, so remove it.
5ee74fb to 1c0d934 Compare
Huh? This makes no sense. Are you sure you are not misunderstanding things? Can you put/link to the exact quote from the doc in here? |
| Oh, I see. It's allowed to pass an uninitialized Taking a second look at this PR (it was years since the last time I looked into it), why are you allocating a string in |
| @nurupo have you also read the linked discussions in #908? AFAICT there we agreed on the exact opposite of what you're saying now. The problem I see with not deep-copying the data into |
| Aha! I have totally forgotten about #908. Like I have said in that issue, we could change the semantics of Also, when I'm not opposed to the change, just want to see if we think that pros outweight the cons. Breaking the API and possibly unintentionally introducing memory corruption bugs into clients by changing the memory ownership model under them shouldn't be done without a good reason. I have yet to see a good reason for making this change though. (Surprisingly, there wasn't any reason provided before your last comment, unless it was discussed on the IRC at the time).
Can you give an example of such a mistake? I'm having hard time understanding as |
True, I'll look into what prevents making
TBH this is the first time I'm hearing that this is the intended behavior, because this not documented in
I think doing this change with the transition to an opaque pointer is the perfect time, since the API changes anyway I'd rather break it once and make it future proof.
qTox was not honoring the (undocumented) lifetime requirement that the The main argument I see for making copies of data passed via setters is simplicity and reliability. The user doesn't need to care about the lifetime of the parameters they set after calling a setter. Additionally all synchronization points are well defined by the functions As for making |
Sounds like the documentation should be improved then. But yeah, you can now stop making
I wouldn't call making getters return values different from what was passed into setters intuitive or simple... That's some spooky action at a distance stuff -- rather unexpected. |
As always :D As for strange things that could happen with current code: Another problem is passing a The problem is that in C there is no way to describe the concept that data is deep copied or just the reference stored in the function signature (see ownership transfer in Rust or modern C++). So we need to document the way we handle it and ideally be consistent throughout our own API. To be consistent with other setters which handle only integral types I'd implement this for strings in a similar "fire and forget" way. |
I looked into #4934 and it's a clear case of CWE-562: Return of Stack Variable Address. It's returning a stack-allocated buffer from a function and somehow expecting it to work. It doesn't even use any of |
| True, but whether you use a setter or assign the value directly to the struct doesn't matter for this kind of problem. I'd even argue that before making |
| I have already explained this, but here we go again, in a bit more structured way this time:
So in short, there are too many drawbacks to this change:
In comparison, leaving things as they are -- toxcore deep copying inside |
| @nurupo Thanks for listing everything in a structured manner. @iphydf @JFreegman I interpreted your comments on this PR in favor of this change, but before I put any more work into it: do you still support changing the API to deep copying |
fixes #908
This change is