uri-whatwg_parser 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +1 -6
- data/lib/uri/whatwg_parser/generic.rb +104 -32
- data/lib/uri/whatwg_parser/version.rb +1 -1
- data/lib/uri/whatwg_parser.rb +68 -48
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 340c89cc9b0c80699547d7daa0a33c3c081250ebee1dd1178a36ee288a484a22
|
|
4
|
+
data.tar.gz: 961034f93393490c76ad015aea1524b27b5955ef38112892d50b2a1e15a3ac50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 987525847dbe6f04d4a2a4c3c8e338d57ebd964d4312528bc16e5e515ba7460922c3fedf08a4151227dbd1fbca11be4af38db6db53e1d741992460fd89c86bd0
|
|
7
|
+
data.tar.gz: 12eae3fe44a8136aa66a55d1aa7e12b172980ae96470f890e34e721fae4c1f3f23155ff1a2e1db305ce2f239cdf239a7db43fe5feb153eb11f3f230c09fd77a4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
## 0.3.1
|
|
2
|
+
|
|
3
|
+
* Fix a bug of parsing Windows drive letter
|
|
4
|
+
* Correctly set a password when a username is nil
|
|
5
|
+
* Fix setter methods behavior with `URI object created by `build` method
|
|
6
|
+
|
|
7
|
+
## 0.3.0
|
|
8
|
+
|
|
9
|
+
* Fix several incorrect parsing processes
|
|
10
|
+
* Fix serialize URL
|
|
11
|
+
|
|
1
12
|
## 0.2.1
|
|
2
13
|
|
|
3
14
|
* Improve the performance of `parse`
|
data/README.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# URI::WhatwgParser
|
|
2
|
-
|
|
3
2
|
Ruby implementation of the [WHATWG URL Living Standard](https://url.spec.whatwg.org/).
|
|
4
3
|
|
|
5
|
-
The latest revision that this package implements of the standard is [
|
|
4
|
+
The latest revision that this package implements of the standard is [14 April 2026](https://url.spec.whatwg.org/commit-snapshots/b11d73b8caefe90403afe19210db05acba897722/)
|
|
6
5
|
|
|
7
6
|
## Installation
|
|
8
7
|
|
|
@@ -27,10 +26,6 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
|
27
26
|
|
|
28
27
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
29
28
|
|
|
30
|
-
## TODO
|
|
31
|
-
|
|
32
|
-
* Support validations
|
|
33
|
-
|
|
34
29
|
## Contributing
|
|
35
30
|
|
|
36
31
|
Bug reports and pull requests are welcome on GitHub at https://github.com/y-yagi/uri-whatwg_parser.
|
|
@@ -3,16 +3,11 @@ require "uri/generic"
|
|
|
3
3
|
module URI
|
|
4
4
|
class WhatwgParser
|
|
5
5
|
module Generic
|
|
6
|
-
def initialize(scheme,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
parser = DEFAULT_PARSER,
|
|
12
|
-
arg_check = false)
|
|
13
|
-
|
|
14
|
-
return super unless URI::DEFAULT_PARSER.is_a?(URI::WhatwgParser)
|
|
15
|
-
return super if registry
|
|
6
|
+
def initialize(scheme, userinfo, host, port, registry, path, opaque, query, fragment, parser = DEFAULT_PARSER, arg_check = false)
|
|
7
|
+
@parsed_by_whatwg_parser = parser.is_a?(URI::WhatwgParser)
|
|
8
|
+
unless parser.is_a?(URI::WhatwgParser)
|
|
9
|
+
return super(scheme, userinfo, host, port, registry, path, opaque, query, fragment, URI::RFC3986_PARSER, arg_check)
|
|
10
|
+
end
|
|
16
11
|
|
|
17
12
|
@scheme = nil
|
|
18
13
|
@user = nil
|
|
@@ -20,6 +15,7 @@ module URI
|
|
|
20
15
|
@host = nil
|
|
21
16
|
@port = nil
|
|
22
17
|
@path = nil
|
|
18
|
+
@raw_path = nil
|
|
23
19
|
@query = nil
|
|
24
20
|
@opaque = nil
|
|
25
21
|
@fragment = nil
|
|
@@ -30,66 +26,69 @@ module URI
|
|
|
30
26
|
self.set_port(port)
|
|
31
27
|
self.set_userinfo(userinfo)
|
|
32
28
|
self.set_path(path)
|
|
33
|
-
|
|
29
|
+
@query = query
|
|
34
30
|
self.set_opaque(opaque)
|
|
35
|
-
|
|
31
|
+
@fragment = fragment
|
|
32
|
+
@raw_path = parser&.path
|
|
36
33
|
|
|
37
34
|
self.set_path("") if !@path && !@opaque
|
|
38
|
-
|
|
35
|
+
parser.parse(to_s) if arg_check
|
|
39
36
|
|
|
40
37
|
@scheme&.freeze
|
|
41
38
|
self.set_port(self.default_port) if self.default_port && !@port
|
|
42
39
|
end
|
|
43
40
|
|
|
44
41
|
def merge(oth)
|
|
45
|
-
|
|
42
|
+
return super unless @parsed_by_whatwg_parser
|
|
43
|
+
|
|
44
|
+
parser.join(self.to_s, oth.to_s)
|
|
46
45
|
end
|
|
47
46
|
alias + merge
|
|
48
47
|
|
|
49
48
|
def scheme=(v)
|
|
50
|
-
return super unless
|
|
49
|
+
return super unless @parsed_by_whatwg_parser
|
|
51
50
|
return if v.nil? || v.empty?
|
|
52
51
|
|
|
53
|
-
parse_result =
|
|
52
|
+
parse_result = parser.split("#{v}:", url: self, state_override: :scheme_start_state)
|
|
54
53
|
set_scheme(parse_result[0])
|
|
55
54
|
set_port(parse_result[3])
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
def user=(v)
|
|
59
|
-
return super unless
|
|
58
|
+
return super unless @parsed_by_whatwg_parser
|
|
60
59
|
return v unless v
|
|
61
60
|
|
|
62
61
|
if host.nil? || host.empty? || scheme == "file"
|
|
63
62
|
raise InvalidURIError, "cannot set user when host is nil or file schme"
|
|
64
63
|
end
|
|
65
|
-
set_user(
|
|
64
|
+
set_user(parser.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
|
|
66
65
|
end
|
|
67
66
|
|
|
68
67
|
def password=(v)
|
|
69
|
-
return super unless
|
|
68
|
+
return super unless @parsed_by_whatwg_parser
|
|
70
69
|
return v unless v
|
|
71
70
|
|
|
72
71
|
if host.nil? || host.empty? || scheme == "file"
|
|
73
72
|
raise InvalidURIError, "cannot set password when host is nil or file schme"
|
|
74
73
|
end
|
|
75
|
-
set_password(
|
|
74
|
+
set_password(parser.utf8_percent_encode_string(v, URI::WhatwgParser::USERINFO_PERCENT_ENCODE_SET))
|
|
76
75
|
end
|
|
77
76
|
|
|
78
77
|
def host=(v)
|
|
79
|
-
return super unless
|
|
78
|
+
return super unless @parsed_by_whatwg_parser
|
|
80
79
|
return if v.nil?
|
|
81
80
|
|
|
82
81
|
if @opaque
|
|
83
|
-
raise InvalidURIError, "cannot set host with
|
|
82
|
+
raise InvalidURIError, "cannot set host with opaque"
|
|
84
83
|
end
|
|
85
84
|
|
|
86
|
-
parse_result =
|
|
85
|
+
parse_result = parser.split(v.to_s, url: self, state_override: :host_state)
|
|
87
86
|
set_host(parse_result[2])
|
|
88
87
|
set_port(parse_result[3])
|
|
89
88
|
end
|
|
90
89
|
|
|
91
90
|
def port=(v)
|
|
92
|
-
return super unless
|
|
91
|
+
return super unless @parsed_by_whatwg_parser
|
|
93
92
|
return if v.nil?
|
|
94
93
|
|
|
95
94
|
if v.to_s.empty?
|
|
@@ -101,24 +100,55 @@ module URI
|
|
|
101
100
|
raise InvalidURIError, "cannot set port when host is nil or scheme is file"
|
|
102
101
|
end
|
|
103
102
|
|
|
104
|
-
parse_result =
|
|
103
|
+
parse_result = parser.split("#{v}:", url: self, state_override: :port_state)
|
|
105
104
|
set_port(parse_result[3])
|
|
106
105
|
end
|
|
107
106
|
|
|
108
107
|
def path=(v)
|
|
109
|
-
return super unless
|
|
108
|
+
return super unless @parsed_by_whatwg_parser
|
|
110
109
|
return if v.nil?
|
|
111
110
|
|
|
112
111
|
if @opaque
|
|
113
112
|
raise InvalidURIError, "path conflicts with opaque"
|
|
114
113
|
end
|
|
115
114
|
|
|
116
|
-
parse_result =
|
|
115
|
+
parse_result = parser.split(v.to_s, url: self, state_override: :path_start_state)
|
|
116
|
+
@raw_path = parser.path
|
|
117
117
|
set_path(parse_result[5])
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
+
def query=(v)
|
|
121
|
+
return super unless @parsed_by_whatwg_parser
|
|
122
|
+
|
|
123
|
+
if v.nil? || v.empty?
|
|
124
|
+
@query = nil
|
|
125
|
+
return
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
v = v.start_with?("?") ? v[1..-1] : v
|
|
129
|
+
@query = +""
|
|
130
|
+
|
|
131
|
+
parse_result = parser.split(v, url: self, state_override: :query_state)
|
|
132
|
+
@query = parse_result[7].to_s
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def fragment=(v)
|
|
136
|
+
return super unless @parsed_by_whatwg_parser
|
|
137
|
+
|
|
138
|
+
if v.nil? || v.empty?
|
|
139
|
+
@fragment = nil
|
|
140
|
+
return
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
v = v.start_with?("#") ? v[1..-1] : v
|
|
144
|
+
@fragment = +""
|
|
145
|
+
|
|
146
|
+
parse_result = parser.split(v, url: self, state_override: :fragment_state)
|
|
147
|
+
@fragment = parse_result[8].to_s
|
|
148
|
+
end
|
|
149
|
+
|
|
120
150
|
def userinfo=(userinfo)
|
|
121
|
-
return super unless
|
|
151
|
+
return super unless @parsed_by_whatwg_parser
|
|
122
152
|
|
|
123
153
|
user, password = split_userinfo(userinfo)
|
|
124
154
|
self.user = user
|
|
@@ -126,17 +156,59 @@ module URI
|
|
|
126
156
|
end
|
|
127
157
|
|
|
128
158
|
def check_opaque(v)
|
|
129
|
-
return super unless
|
|
159
|
+
return super unless @parsed_by_whatwg_parser
|
|
160
|
+
|
|
130
161
|
return v unless v
|
|
131
162
|
|
|
132
|
-
if @host || @port || @user
|
|
133
|
-
raise InvalidURIError, "cannot set opaque with host, port,
|
|
163
|
+
if @host || @port || @user
|
|
164
|
+
raise InvalidURIError, "cannot set opaque with host, port, or userinfo"
|
|
134
165
|
end
|
|
135
166
|
|
|
136
167
|
self.set_opaque(v)
|
|
137
|
-
|
|
168
|
+
# NOTE: WHATWG URL Living Standard doesn't define "opaque" setter. So parse a URL whole.
|
|
169
|
+
parser.parse(to_s)
|
|
138
170
|
true
|
|
139
171
|
end
|
|
172
|
+
|
|
173
|
+
def to_s
|
|
174
|
+
return super unless @parsed_by_whatwg_parser
|
|
175
|
+
|
|
176
|
+
str = "".dup
|
|
177
|
+
if @scheme
|
|
178
|
+
str << @scheme
|
|
179
|
+
str << ":"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
if @host || %w[file postgres].include?(@scheme)
|
|
183
|
+
str << "//"
|
|
184
|
+
end
|
|
185
|
+
if self.userinfo
|
|
186
|
+
str << self.userinfo
|
|
187
|
+
str << "@"
|
|
188
|
+
end
|
|
189
|
+
if @host
|
|
190
|
+
str << @host
|
|
191
|
+
end
|
|
192
|
+
if @port && @port != self.default_port
|
|
193
|
+
str << ":"
|
|
194
|
+
str << @port.to_s
|
|
195
|
+
end
|
|
196
|
+
if @host.nil? && @opaque.nil? && @raw_path && @raw_path.length > 1 && @raw_path[0] == ""
|
|
197
|
+
str << "/."
|
|
198
|
+
end
|
|
199
|
+
str << @path if @path
|
|
200
|
+
str << @opaque if @opaque
|
|
201
|
+
if @query
|
|
202
|
+
str << "?"
|
|
203
|
+
str << @query
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
if @fragment
|
|
207
|
+
str << "#"
|
|
208
|
+
str << @fragment
|
|
209
|
+
end
|
|
210
|
+
str
|
|
211
|
+
end
|
|
140
212
|
end
|
|
141
213
|
end
|
|
142
214
|
end
|
data/lib/uri/whatwg_parser.rb
CHANGED
|
@@ -25,7 +25,7 @@ module URI
|
|
|
25
25
|
|
|
26
26
|
WINDOWS_DRIVE_LETTER = Regexp.new("\\A([a-zA-Z][:|])\\z")
|
|
27
27
|
NORMALIZED_WINDOWS_DRIVE_LETTER = Regexp.new("\\A([a-zA-Z][:])\\z")
|
|
28
|
-
|
|
28
|
+
FILE_OTHERWISE_CODE_POINTS = Set["/", "\\", "?", "#"]
|
|
29
29
|
|
|
30
30
|
VALID_SIGNS_FOR_SCHEME = Set["+", "-", "."]
|
|
31
31
|
DELIMITER_SIGNS = Set["/", "?", "#"]
|
|
@@ -36,6 +36,8 @@ module URI
|
|
|
36
36
|
ASCII_ALPHA_UPPERCASE = Set.new(("A".."Z").to_a)
|
|
37
37
|
ASCII_DIGIT = Set.new(("0".."9").to_a)
|
|
38
38
|
|
|
39
|
+
attr_reader :path
|
|
40
|
+
|
|
39
41
|
def initialize
|
|
40
42
|
reset
|
|
41
43
|
@host_parser = HostParser.new
|
|
@@ -46,7 +48,7 @@ module URI
|
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def parse(input, base: nil, url: nil, state_override: nil) # :nodoc:
|
|
49
|
-
URI.for(*self.split(input, base: base, url: url, state_override: state_override))
|
|
51
|
+
URI.for(*self.split(input, base: base, url: url, state_override: state_override), self)
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
def split(input, base: nil, url: nil, state_override: nil) # :nodoc:
|
|
@@ -54,8 +56,8 @@ module URI
|
|
|
54
56
|
@base = nil
|
|
55
57
|
if base != nil
|
|
56
58
|
ary = split(base, base: nil)
|
|
57
|
-
@base = { scheme: ary[0], userinfo: ary[1], host: ary[2], port: ary[3],
|
|
58
|
-
@
|
|
59
|
+
@base = { scheme: ary[0], userinfo: ary[1], host: ary[2], port: ary[3], query: ary[7], fragment: ary[8]}
|
|
60
|
+
@base_path = @path
|
|
59
61
|
reset
|
|
60
62
|
end
|
|
61
63
|
|
|
@@ -94,9 +96,19 @@ module URI
|
|
|
94
96
|
@pos += 1
|
|
95
97
|
end
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
if @password
|
|
100
|
+
userinfo = "#{@username}:#{@password}"
|
|
101
|
+
else
|
|
102
|
+
userinfo = @username
|
|
103
|
+
end
|
|
104
|
+
if @path
|
|
105
|
+
if @path.is_a?(Array)
|
|
106
|
+
path = "/#{@path.join("/")}"
|
|
107
|
+
else
|
|
108
|
+
opaque = @path
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
[@parse_result[:scheme], userinfo, @parse_result[:host], @parse_result[:port], nil, path, opaque, @parse_result[:query], @parse_result[:fragment]]
|
|
100
112
|
end
|
|
101
113
|
|
|
102
114
|
def join(*uris)
|
|
@@ -143,10 +155,10 @@ module URI
|
|
|
143
155
|
@at_sign_seen = nil
|
|
144
156
|
@password_token_seen = nil
|
|
145
157
|
@inside_brackets = nil
|
|
146
|
-
@
|
|
158
|
+
@path = nil
|
|
147
159
|
@username = nil
|
|
148
160
|
@password = nil
|
|
149
|
-
@parse_result = {
|
|
161
|
+
@parse_result = {}
|
|
150
162
|
@state_override = nil
|
|
151
163
|
@state = :scheme_start_state
|
|
152
164
|
@special_url = nil
|
|
@@ -207,7 +219,7 @@ module URI
|
|
|
207
219
|
@state = :path_or_authority_state
|
|
208
220
|
@pos += 1
|
|
209
221
|
else
|
|
210
|
-
@
|
|
222
|
+
@path = +""
|
|
211
223
|
@state = :opaque_path_state
|
|
212
224
|
end
|
|
213
225
|
elsif @state_override.nil?
|
|
@@ -220,14 +232,14 @@ module URI
|
|
|
220
232
|
end
|
|
221
233
|
|
|
222
234
|
def no_scheme_state(c)
|
|
223
|
-
raise ParseError, "scheme is missing" if @base.nil? || (
|
|
235
|
+
raise ParseError, "scheme is missing" if @base.nil? || (has_opaque_path?(@base_path) && c != "#")
|
|
224
236
|
|
|
225
|
-
if
|
|
237
|
+
if has_opaque_path?(@base_path) && c == "#"
|
|
226
238
|
@parse_result[:scheme] = @base[:scheme]
|
|
227
239
|
@special_url = special_url?(@base[:scheme])
|
|
228
|
-
@
|
|
240
|
+
@path = @base_path
|
|
229
241
|
@parse_result[:query] = @base[:query]
|
|
230
|
-
@parse_result[:fragment] =
|
|
242
|
+
@parse_result[:fragment] = +""
|
|
231
243
|
@state = :fragment_state
|
|
232
244
|
elsif @base[:scheme] != "file"
|
|
233
245
|
@state = :relative_state
|
|
@@ -268,14 +280,14 @@ module URI
|
|
|
268
280
|
@username, @password = @base[:userinfo].split(":") if @base[:userinfo]
|
|
269
281
|
@parse_result[:host] = @base[:host]
|
|
270
282
|
@parse_result[:port] = @base[:port]
|
|
271
|
-
@
|
|
283
|
+
@path = @base_path
|
|
272
284
|
@parse_result[:query] = @base[:query]
|
|
273
285
|
|
|
274
286
|
if c == "?"
|
|
275
|
-
@parse_result[:query] =
|
|
287
|
+
@parse_result[:query] = +""
|
|
276
288
|
@state = :query_state
|
|
277
289
|
elsif c == "#"
|
|
278
|
-
@parse_result[:fragment] =
|
|
290
|
+
@parse_result[:fragment] = +""
|
|
279
291
|
@state = :fragment_state
|
|
280
292
|
elsif !c.nil?
|
|
281
293
|
@parse_result[:query] = nil
|
|
@@ -386,7 +398,7 @@ module URI
|
|
|
386
398
|
@buffer << c
|
|
387
399
|
elsif c.nil? || DELIMITER_SIGNS.include?(c) || (@special_url && c == "\\") || @state_override
|
|
388
400
|
unless @buffer.empty?
|
|
389
|
-
port =
|
|
401
|
+
port = @buffer.to_i
|
|
390
402
|
raise ParseError, "port is invalid value" if port < 0 || port > 65535
|
|
391
403
|
if SPECIAL_SCHEME[@parse_result[:scheme]] == port
|
|
392
404
|
@parse_result[:port] = nil
|
|
@@ -401,7 +413,6 @@ module URI
|
|
|
401
413
|
end
|
|
402
414
|
end
|
|
403
415
|
|
|
404
|
-
raise ParseError, "port is invalid value" if @state_override
|
|
405
416
|
@state = :path_start_state
|
|
406
417
|
@pos -= 1
|
|
407
418
|
else
|
|
@@ -413,24 +424,24 @@ module URI
|
|
|
413
424
|
@parse_result[:scheme] = "file"
|
|
414
425
|
@special_url = true
|
|
415
426
|
@parse_result[:host] = nil
|
|
416
|
-
|
|
417
427
|
if c == "/" || c == "\\"
|
|
418
428
|
@state = :file_slash_state
|
|
419
429
|
elsif !@base.nil? && @base[:scheme] == "file"
|
|
420
430
|
@parse_result[:host] = @base[:host]
|
|
431
|
+
@path = @base_path
|
|
421
432
|
@parse_result[:query] = @base[:query]
|
|
422
433
|
if c == "?"
|
|
423
|
-
@parse_result[:query] =
|
|
434
|
+
@parse_result[:query] = +""
|
|
424
435
|
@state = :query_state
|
|
425
436
|
elsif c == "#"
|
|
426
|
-
@parse_result[:fragment] =
|
|
437
|
+
@parse_result[:fragment] = +""
|
|
427
438
|
@state = :fragment_state
|
|
428
439
|
elsif !c.nil?
|
|
429
440
|
@parse_result[:query] = nil
|
|
430
441
|
if !starts_with_windows_drive_letter?(rest)
|
|
431
442
|
shorten_url_path
|
|
432
443
|
else
|
|
433
|
-
@
|
|
444
|
+
@path = nil
|
|
434
445
|
end
|
|
435
446
|
@state = :path_state
|
|
436
447
|
@pos -= 1
|
|
@@ -447,11 +458,9 @@ module URI
|
|
|
447
458
|
else
|
|
448
459
|
if !@base.nil? && @base[:scheme] == "file"
|
|
449
460
|
@parse_result[:host] = @base[:host]
|
|
450
|
-
if !starts_with_windows_drive_letter?(rest) && @
|
|
451
|
-
if @
|
|
452
|
-
|
|
453
|
-
@paths[0] = @base_paths[0]
|
|
454
|
-
end
|
|
461
|
+
if !starts_with_windows_drive_letter?(rest) && @base_path && normalized_windows_drive_letter?(@base_path[0])
|
|
462
|
+
@path = [] if @path.nil?
|
|
463
|
+
@path << @base_path[0]
|
|
455
464
|
end
|
|
456
465
|
end
|
|
457
466
|
@state = :path_state
|
|
@@ -493,45 +502,47 @@ module URI
|
|
|
493
502
|
@pos -= 1 if c != "/" && c != "\\"
|
|
494
503
|
@state = :path_state
|
|
495
504
|
elsif !@state_override && c == "?"
|
|
505
|
+
@parse_result[:query] = +""
|
|
496
506
|
@state = :query_state
|
|
497
507
|
elsif !@state_override && c == "#"
|
|
508
|
+
@parse_result[:fragment] = +""
|
|
498
509
|
@state = :fragment_state
|
|
499
510
|
elsif c != nil
|
|
500
511
|
@pos -= 1 if c != "/"
|
|
501
512
|
@state = :path_state
|
|
502
513
|
elsif @state_override && @parse_result[:host].nil?
|
|
503
|
-
@
|
|
504
|
-
@
|
|
514
|
+
@path ||= []
|
|
515
|
+
@path << ""
|
|
505
516
|
end
|
|
506
517
|
end
|
|
507
518
|
|
|
508
519
|
def path_state(c)
|
|
509
|
-
@
|
|
520
|
+
@path ||= []
|
|
510
521
|
|
|
511
522
|
if (c.nil? || c == "/") || (@special_url && c == "\\") || (!@state_override && (c == "?" || c == "#"))
|
|
512
523
|
if double_dot_path_segments?(@buffer)
|
|
513
524
|
shorten_url_path
|
|
514
525
|
|
|
515
526
|
if c != "/" && !(@special_url && c == "\\")
|
|
516
|
-
@
|
|
527
|
+
@path << ""
|
|
517
528
|
end
|
|
518
529
|
elsif single_dot_path_segments?(@buffer) && c != "/" && !((@special_url && c == "\\"))
|
|
519
|
-
@
|
|
530
|
+
@path << ""
|
|
520
531
|
elsif !single_dot_path_segments?(@buffer)
|
|
521
|
-
if @parse_result[:scheme] == "file" && @
|
|
532
|
+
if @parse_result[:scheme] == "file" && @path.empty? && windows_drive_letter?(@buffer)
|
|
522
533
|
@buffer[1] = ":"
|
|
523
534
|
end
|
|
524
535
|
|
|
525
|
-
@
|
|
536
|
+
@path << @buffer
|
|
526
537
|
end
|
|
527
538
|
|
|
528
539
|
@buffer = +""
|
|
529
540
|
|
|
530
541
|
if c == "?"
|
|
531
|
-
@parse_result[:query] =
|
|
542
|
+
@parse_result[:query] = +""
|
|
532
543
|
@state = :query_state
|
|
533
544
|
elsif c == "#"
|
|
534
|
-
@parse_result[:
|
|
545
|
+
@parse_result[:fragment] = +""
|
|
535
546
|
@state = :fragment_state
|
|
536
547
|
end
|
|
537
548
|
else
|
|
@@ -541,20 +552,20 @@ module URI
|
|
|
541
552
|
|
|
542
553
|
def opaque_path_state(c)
|
|
543
554
|
if c == "?"
|
|
544
|
-
@parse_result[:query] =
|
|
555
|
+
@parse_result[:query] = +""
|
|
545
556
|
@state = :query_state
|
|
546
557
|
elsif c == "#"
|
|
547
|
-
@parse_result[:fragment] =
|
|
558
|
+
@parse_result[:fragment] = +""
|
|
548
559
|
@state = :fragment_state
|
|
549
560
|
elsif c == " "
|
|
550
561
|
first_of_rest = @input_chars[@pos + 1]
|
|
551
562
|
if first_of_rest == "?" || first_of_rest == "#"
|
|
552
|
-
@
|
|
563
|
+
@path += "%20"
|
|
553
564
|
else
|
|
554
|
-
@
|
|
565
|
+
@path += " "
|
|
555
566
|
end
|
|
556
567
|
elsif !c.nil?
|
|
557
|
-
@
|
|
568
|
+
@path += utf8_percent_encode(c, C0_CONTROL_PERCENT_ENCODE_SET)
|
|
558
569
|
end
|
|
559
570
|
end
|
|
560
571
|
|
|
@@ -564,7 +575,10 @@ module URI
|
|
|
564
575
|
# TODO: We need to consider encoding here.
|
|
565
576
|
@parse_result[:query] = utf8_percent_encode_string(@buffer, query_percent_encode_set)
|
|
566
577
|
@buffer.clear
|
|
567
|
-
|
|
578
|
+
if c == "#"
|
|
579
|
+
@parse_result[:fragment] = +""
|
|
580
|
+
@state = :fragment_state
|
|
581
|
+
end
|
|
568
582
|
elsif !c.nil?
|
|
569
583
|
@buffer << c
|
|
570
584
|
end
|
|
@@ -580,7 +594,9 @@ module URI
|
|
|
580
594
|
end
|
|
581
595
|
|
|
582
596
|
def starts_with_windows_drive_letter?(str)
|
|
583
|
-
|
|
597
|
+
return false if str.length < 2
|
|
598
|
+
return false unless windows_drive_letter?(str[0, 2])
|
|
599
|
+
str.length == 2 || FILE_OTHERWISE_CODE_POINTS.include?(str[2])
|
|
584
600
|
end
|
|
585
601
|
|
|
586
602
|
def normalized_windows_drive_letter?(str)
|
|
@@ -600,9 +616,9 @@ module URI
|
|
|
600
616
|
end
|
|
601
617
|
|
|
602
618
|
def shorten_url_path
|
|
603
|
-
return if @
|
|
604
|
-
return if @parse_result[:scheme] == "file" && @
|
|
605
|
-
@
|
|
619
|
+
return if @path.nil? || @path.is_a?(String)
|
|
620
|
+
return if @parse_result[:scheme] == "file" && @path.length == 1 && normalized_windows_drive_letter?(@path.first)
|
|
621
|
+
@path.pop
|
|
606
622
|
end
|
|
607
623
|
|
|
608
624
|
def includes_credentials?
|
|
@@ -610,7 +626,7 @@ module URI
|
|
|
610
626
|
end
|
|
611
627
|
|
|
612
628
|
def rest
|
|
613
|
-
@input_chars[@pos
|
|
629
|
+
@input_chars[@pos..]&.join
|
|
614
630
|
end
|
|
615
631
|
|
|
616
632
|
def convert_to_uri(uri)
|
|
@@ -638,6 +654,10 @@ module URI
|
|
|
638
654
|
end
|
|
639
655
|
end
|
|
640
656
|
end
|
|
657
|
+
|
|
658
|
+
def has_opaque_path?(path)
|
|
659
|
+
path.is_a?(String)
|
|
660
|
+
end
|
|
641
661
|
end
|
|
642
662
|
|
|
643
663
|
WHATWG_PARSER = URI::WhatwgParser.new
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: uri-whatwg_parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yuji Yaginuma
|
|
@@ -66,14 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
66
66
|
requirements:
|
|
67
67
|
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 3.
|
|
69
|
+
version: 3.0.0
|
|
70
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - ">="
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
74
|
version: '0'
|
|
75
75
|
requirements: []
|
|
76
|
-
rubygems_version: 4.0.
|
|
76
|
+
rubygems_version: 4.0.10
|
|
77
77
|
specification_version: 4
|
|
78
78
|
summary: Ruby implementation of the WHATWG URL Living Standard
|
|
79
79
|
test_files: []
|