Skip to content

Commit a4035dd

Browse files
authored
net.urllib: use option instead of pointer for the Userinfo field (fix #24650) (#25401)
1 parent 1dd172e commit a4035dd

3 files changed

Lines changed: 44 additions & 31 deletions

File tree

‎vlib/net/http/http_proxy.v‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub fn new_http_proxy(raw_url string) !&HttpProxy {
3131
url.raw_path = ''
3232
url.raw_query = ''
3333
url.fragment = ''
34+
mut username := ''
35+
mut password := ''
3436

3537
str_url := url.str()
3638

@@ -50,10 +52,15 @@ pub fn new_http_proxy(raw_url string) !&HttpProxy {
5052
return error('Unknown port')
5153
}
5254

55+
if u := url.user {
56+
username = u.username
57+
password = u.password
58+
}
59+
5360
return &HttpProxy{
5461
scheme: scheme
55-
username: url.user.username
56-
password: url.user.password
62+
username: username
63+
password: password
5764
host: host
5865
hostname: url.hostname()
5966
port: port

‎vlib/net/urllib/urllib.v‎

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -317,14 +317,14 @@ fn escape(s string, mode EncodingMode) string {
317317
pub struct URL {
318318
pub mut:
319319
scheme string
320-
opaque string // encoded opaque data
321-
user &Userinfo = unsafe { nil } // username and password information
322-
host string // host or host:port
323-
path string // path (relative paths may omit leading slash)
324-
raw_path string // encoded path hint (see escaped_path method)
325-
force_query bool // append a query ('?') even if raw_query is empty
326-
raw_query string // encoded query values, without '?'
327-
fragment string // fragment for references, without '#'
320+
opaque string // encoded opaque data
321+
user ?Userinfo // username and password information
322+
host string // host or host:port
323+
path string // path (relative paths may omit leading slash)
324+
raw_path string // encoded path hint (see escaped_path method)
325+
force_query bool // append a query ('?') even if raw_query is empty
326+
raw_query string // encoded query values, without '?'
327+
fragment string // fragment for references, without '#'
328328
}
329329

330330
// debug returns a string representation of *ALL* the fields of the given URL
@@ -334,8 +334,8 @@ pub fn (url &URL) debug() string {
334334

335335
// user returns a Userinfo containing the provided username
336336
// and no password set.
337-
pub fn user(username string) &Userinfo {
338-
return &Userinfo{
337+
pub fn user(username string) Userinfo {
338+
return Userinfo{
339339
username: username
340340
password: ''
341341
password_set: false
@@ -350,8 +350,8 @@ pub fn user(username string) &Userinfo {
350350
// ``is NOT RECOMMENDED, because the passing of authentication
351351
// information in clear text (such as URI) has proven to be a
352352
// security risk in almost every case where it has been used.''
353-
fn user_password(username string, password string) &Userinfo {
354-
return &Userinfo{username, password, true}
353+
fn user_password(username string, password string) Userinfo {
354+
return Userinfo{username, password, true}
355355
}
356356

357357
// The Userinfo type is an immutable encapsulation of username and
@@ -365,13 +365,13 @@ pub:
365365
password_set bool
366366
}
367367

368-
fn (u &Userinfo) empty() bool {
369-
return isnil(u) || (u.username == '' && u.password == '')
368+
fn (u Userinfo) empty() bool {
369+
return u.username == '' && u.password == ''
370370
}
371371

372372
// string returns the encoded userinfo information in the standard form
373373
// of 'username[:password]'.
374-
fn (u &Userinfo) str() string {
374+
fn (u Userinfo) str() string {
375375
if u.empty() {
376376
return ''
377377
}
@@ -471,7 +471,7 @@ fn parse_url(rawurl string, via_request bool) !URL {
471471
return error(error_msg('parse_url: empty URL', rawurl))
472472
}
473473
mut url := URL{
474-
user: unsafe { nil }
474+
user: none
475475
}
476476
if rawurl == '*' {
477477
url.path = '*'
@@ -533,7 +533,7 @@ fn parse_url(rawurl string, via_request bool) !URL {
533533
}
534534

535535
struct ParseAuthorityRes {
536-
user &Userinfo
536+
user ?Userinfo
537537
host string
538538
}
539539

@@ -697,7 +697,7 @@ fn valid_optional_port(port string) bool {
697697
//
698698
// In the second form, the following rules apply:
699699
// - if u.scheme is empty, scheme: is omitted.
700-
// - if u.user is nil, userinfo@ is omitted.
700+
// - if u.user is none, userinfo@ is omitted.
701701
// - if u.host is empty, host/ is omitted.
702702
// - if u.scheme and u.host are empty and u.user is nil,
703703
// the entire scheme://userinfo@host/ is omitted.
@@ -714,12 +714,13 @@ pub fn (u URL) str() string {
714714
if u.opaque != '' {
715715
buf.write_string(u.opaque)
716716
} else {
717-
if u.scheme != '' || u.host != '' || !u.user.empty() {
718-
if u.host != '' || u.path != '' || !u.user.empty() {
717+
user := u.user or { Userinfo{} }
718+
if u.scheme != '' || u.host != '' || !user.empty() {
719+
if u.host != '' || u.path != '' || !user.empty() {
719720
buf.write_string('//')
720721
}
721-
if !u.user.empty() {
722-
buf.write_string(u.user.str())
722+
if !user.empty() {
723+
buf.write_string(user.str())
723724
buf.write_string('@')
724725
}
725726
if u.host != '' {
@@ -921,7 +922,8 @@ pub fn (u &URL) resolve_reference(ref &URL) !URL {
921922
if ref.scheme == '' {
922923
url.scheme = u.scheme
923924
}
924-
if ref.scheme != '' || ref.host != '' || !ref.user.empty() {
925+
ref_user := ref.user or { Userinfo{} }
926+
if ref.scheme != '' || ref.host != '' || !ref_user.empty() {
925927
// The 'absoluteURI' or 'net_path' cases.
926928
// We can ignore the error from set_path since we know we provided a
927929
// validly-escaped path.

‎vlib/net/urllib/urllib_test.v‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn test_parse_empty_query_one() {
7575
assert query_str == query_encode
7676
}
7777

78-
// testing the case where the query as empity value
78+
// testing the case where the query as empty value
7979
// e.g https://www.vlang.dev?
8080
fn test_parse_empty_query_two() {
8181
query_str := ''
@@ -112,9 +112,11 @@ fn test_parse() {
112112

113113
test_url := 'https://joe:pass@www.mydomain.com:8080/som/url?param1=test1&param2=test2&foo=bar#testfragment'
114114
u := urllib.parse(test_url)!
115-
assert u.scheme == 'https' && u.hostname() == 'www.mydomain.com' && u.port() == '8080'
116-
&& u.path == '/som/url' && u.fragment == 'testfragment' && u.user.username == 'joe'
117-
&& u.user.password == 'pass'
115+
if user := u.user {
116+
assert u.scheme == 'https' && u.hostname() == 'www.mydomain.com' && u.port() == '8080'
117+
&& u.path == '/som/url' && u.fragment == 'testfragment' && user.username == 'joe'
118+
&& user.password == 'pass'
119+
}
118120

119121
v := urllib.parse('https://vip.ffzy-online4.com/20230205/6094_d2720761/index.m3u8')!.resolve_reference(urllib.parse('2000k/hls/mixed.m3u8')!)!
120122
assert v.str() == 'https://vip.ffzy-online4.com/20230205/6094_d2720761/2000k/hls/mixed.m3u8'
@@ -129,8 +131,10 @@ fn test_parse_authority() {
129131

130132
for url, expected in test_urls {
131133
u := urllib.parse(url)!
132-
assert u.user.username == expected[0]
133-
assert u.user.password == expected[1]
134+
if user := u.user {
135+
assert user.username == expected[0]
136+
assert user.password == expected[1]
137+
}
134138
}
135139
}
136140

0 commit comments

Comments
 (0)