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

url: Fix parsing for when 'file' is the default protocol #1124

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

url: Fix parsing for when 'file' is the default protocol. draft1

Follow-up to 3463408.

Prior to 3463408 file:// hostnames were silently stripped.

Prior to this commit it did not work when a schemeless url was used with
file as the default protocol.

Ref: https://curl.haxx.se/mail/lib-2016-11/0081.html
Ref: #1124
  • Loading branch information...
jay committed Nov 13, 2016
commit 3cf83036c9a16b0af605d770e7df048b1b69f8cf
@@ -4258,11 +4258,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
char *fragment;
char *path = data->state.path;
char *query;
int i;
int rc;
char protobuf[16] = "";
const char *protop = "";
CURLcode result;
bool rebuild_url = FALSE;
bool url_has_scheme = FALSE;

*prot_missing = FALSE;

@@ -4281,9 +4283,32 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
* proxy -- and we don't know if we will need to use SSL until we parse the
* url ...
************************************************************/
if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
protobuf, path)) &&
strcasecompare(protobuf, "file")) {
if(data->change.url[0] == ':') {
failf(data, "Bad URL, colon is first character");
return CURLE_URL_MALFORMAT;
}
for(i = 0; i < 16 && data->change.url[i]; ++i) {
if(data->change.url[i] == '/')
break;
if(data->change.url[i] == ':') {
url_has_scheme = TRUE;
break;
}
}
/* handle the file: scheme */
if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) ||
(!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] &&
strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) {
if(url_has_scheme)
rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path);
else
rc = sscanf(data->change.url, "%[^\n]", path);

if(rc != 1) {
failf(data, "Bad URL");
return CURLE_URL_MALFORMAT;
}

if(path[0] == '/' && path[1] == '/') {
/* Allow omitted hostname (e.g. file:/<path>). This is not strictly
* speaking a valid file: URL by RFC 1738, but treating file:/<path> as
@@ -4294,6 +4319,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
memory areas overlap! */
memmove(path, path + 2, strlen(path + 2)+1);
}

/*
* we deal with file://<host>/<path> differently since it supports no
* hostname other than "localhost" and "127.0.0.1", which is unique among
@@ -4305,7 +4331,8 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
char *ptr;
if(!checkprefix("localhost/", path) &&
!checkprefix("127.0.0.1/", path)) {
failf(data, "Valid host name with slash missing in URL");
failf(data, "Invalid file://hostname/, "
"expected localhost or 127.0.0.1 or none");

This comment has been minimized.

Copy link
@bagder

bagder Nov 13, 2016

Member

We're back to what we discussed on the mailing list. I tried to make the message also convey that there needs to be a valid hostname and slash in the URL as this message will be shown for file://locahost as well, which does have a valid host name but no slash. But sure, error messages are hard and if you think this is better then I don't mind.

return CURLE_URL_MALFORMAT;
}
ptr = &path[9]; /* now points to the slash after the host */
@@ -4342,7 +4369,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
path[0]=0;

rc = sscanf(data->change.url,
"%15[^\n:]:%3[/]%[^\n/?#]%[^\n]",
"%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
protobuf, slashbuf, conn->host.name, path);
if(2 == rc) {
failf(data, "Bad URL");
@@ -120,7 +120,7 @@ test1112 test1113 test1114 test1115 test1116 test1117 test1118 test1119 \
test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \
test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \
test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \
test1144 \
test1144 test1145 test1146 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
test1216 test1217 test1218 test1219 \
@@ -0,0 +1,40 @@
<testcase>
<info>
<keywords>
FILE
</keywords>
</info>

<reply>
</reply>

# Client-side
<client>
<server>
file
</server>
<name>
file:// bad host
</name>
# This command should not succeed since we only accept
# file:/// file://localhost/ file://127.0.0.1/
<command>
file://bad-host%PWD/log/test1145.txt
</command>
<file name="log/test1145.txt">
foo
bar
bar
foo
moo
</file>
</client>

# Verify data after the test has been "shot"
<verify>
# CURLE_URL_MALFORMAT is error code 3
<errorcode>
3
</errorcode>
</verify>
</testcase>
@@ -0,0 +1,45 @@
<testcase>
<info>
<keywords>
FILE
--proto-default
</keywords>
</info>

<reply>
<data>
foo
bar
bar
foo
moo
</data>
</reply>

# Client-side
<client>
<server>
file
</server>
<name>
--proto-default file
</name>
<command>
--proto-default file %PWD/log/test1146.txt
</command>
<file name="log/test1146.txt">
foo
bar
bar
foo
moo
</file>
</client>

# Verify data after the test has been "shot"
<verify>
<errorcode>
0
</errorcode>
</verify>
</testcase>
@@ -27,7 +27,7 @@ http
lib1534
</tool>
<name>
Test CURLINFO_RESPONSE_CODE
CURLINFO_FILETIME init and reset
</name>
<command>
http://%HOSTIP:%HTTPPORT/1534
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.