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

Take const CURLU* arg in URL observers #10708

Closed
wants to merge 3 commits into from
Closed

Conversation

rcombs
Copy link
Contributor

@rcombs rcombs commented Mar 8, 2023

Currently, curl_url_dup and curl_url_get each take a non-const CURLU* arg. In the case of _dup, there seems to be no reason for this; it never actually mutates the input. curl_url_get, though, actually can mutate its input; this is unintuitive and undocumented. This PR ensures that _get never mutates its input (this is a fairly trivial set of changes), and changes the arg type for those two functions to const CURLU*.

This changes the signatures for two public functions, but the result is both API- and ABI-compatible with existing code, so it shouldn't require a major semver bump.

If this change is rejected for some reason, the documentation should be updated to clearly indicate that curl_url_get can mutate its input.

@bagder
Copy link
Member

bagder commented Mar 8, 2023

curl_url_get, though, actually can mutate its input; this is unintuitive and undocumented

Can you elaborate on this. When or how would it "mutate" its input?

@rcombs
Copy link
Contributor Author

rcombs commented Mar 8, 2023

See the second commit: it modifies the path member by setting it to strdup("/") if it was previously unset, and modifies the host member by freeing the existing value and replacing it with the same string rewritten to escape %s.

The latter seems like an outright bug; see the output from this test program, linked against the current code:

#include <curl/curl.h>

int main()
{
  CURLU* u = curl_url();
  curl_url_set(u, CURLUPART_URL, "https://test%test:8080/test", 0);

  char *str;
  curl_url_get(u, CURLUPART_URL, &str, 0);
  printf("%s\n", str);
  curl_url_get(u, CURLUPART_URL, &str, 0);
  printf("%s\n", str);
  curl_url_get(u, CURLUPART_URL, &str, 0);
  printf("%s\n", str);

  return 0;
}
https://test%25test:8080/test
https://test%2525test:8080/test
https://test%252525test:8080/test

The function escapes percent signs in host, but then saves the resulting escaped string back into the object. This means that each time we request the CURLUPART_URL, the host gets another 25! This bug would've been much more difficult to introduce had the argument been const to begin with.

@bagder
Copy link
Member

bagder commented Mar 8, 2023

That "mutation" is a bug.

@rcombs
Copy link
Contributor Author

rcombs commented Mar 8, 2023

Makes sense; so, this PR fixes that bug, and also makes it more difficult for similar bugs to recur in the future.

@bagder
Copy link
Member

bagder commented Mar 8, 2023

Thinking further, I believe test%test is an illegal host name and should be rejected by the parser. I'll take a look at that (that's independent from this PR).

Copy link
Member

@bagder bagder left a comment

Choose a reason for hiding this comment

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

For all I can tell, adding const like this should be fine both API and ABI wise.

bagder added a commit that referenced this pull request Mar 8, 2023
Update test 1560 to verify

Ref: #10708
bagder added a commit that referenced this pull request Mar 8, 2023
Update test 1560 to verify

Ref: #10708
Closes #10711
@bagder bagder closed this in 95cb7d3 Mar 8, 2023
@bagder
Copy link
Member

bagder commented Mar 8, 2023

Thanks!

bagder pushed a commit that referenced this pull request Mar 8, 2023
bch pushed a commit to bch/curl that referenced this pull request Jul 19, 2023
Update test 1560 to verify

Ref: curl#10708
Closes curl#10711
bch pushed a commit to bch/curl that referenced this pull request Jul 19, 2023
bch pushed a commit to bch/curl that referenced this pull request Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

3 participants