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

setopt() uses SvPV(), doesn’t document whether it’s for bytes or characters #60

Open
FGasper opened this issue Feb 16, 2021 · 0 comments

Comments

@FGasper
Copy link
Contributor

FGasper commented Feb 16, 2021

> perl -Mstrict -w -e'use Net::Curl::Easy qw(:constants); my $payload = "épée"; my $easy = Net::Curl::Easy->new(); $easy->setopt( +CURLOPT_URL, "http://example.com" ); $easy->setopt( CURLOPT_VERBOSE, 1 ); $easy->setopt( +CURLOPT_COPYPOSTFIELDS, $payload ); $easy->perform()' >/dev/null
* About to connect() to example.com port 80 (#0)
*   Trying 2606:2800:220:1:248:1893:25c8:1946...
* Connected to example.com (2606:2800:220:1:248:1893:25c8:1946) port 80 (#0)
> POST / HTTP/1.1
Host: example.com
Accept: */*
Content-Length: 6
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 6 out of 6 bytes
<snip>

Note that the upload size is 6 bytes.

But if you change the SV’s internal representation, the output also changes:

> perl -MJSON -Mstrict -w -e'use Net::Curl::Easy qw(:constants); my $payload = "épée"; $payload = JSON::decode_json( JSON::encode_json([$payload]) )->[0]; my $easy = Net::Curl::Easy->new(); $easy->setopt( +CURLOPT_URL, "http://example.com" ); $easy->setopt( CURLOPT_VERBOSE, 1 ); $easy->setopt( +CURLOPT_COPYPOSTFIELDS, $payload ); $easy->perform()' >/dev/null
* About to connect() to example.com port 80 (#0)
*   Trying 2606:2800:220:1:248:1893:25c8:1946...
* Connected to example.com (2606:2800:220:1:248:1893:25c8:1946) port 80 (#0)
> POST / HTTP/1.1
Host: example.com
Accept: */*
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 10 out of 10 bytes
<snip>

Pure Perl code isn’t supposed to have to care about a string’s internal representation, but this behaviour of Net::Curl forces it.

The proper fix is probably to create a setopt_bytes that always treats the given SV as a byte string. (So if it’s upgraded, what curl gets from Perl will be the downgraded variant.)

Additionally, the documentation should be updated to advise of this situation with plain setopt().

A workaround is to call utf8::downgrade() before giving the value to setopt().

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

No branches or pull requests

1 participant