mechanize 2.7.6 → 2.8.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of mechanize might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/ci-test.yml +53 -0
- data/.yardopts +8 -0
- data/{CHANGELOG.rdoc → CHANGELOG.md} +136 -87
- data/EXAMPLES.rdoc +1 -24
- data/Gemfile +1 -4
- data/{LICENSE.rdoc → LICENSE.txt} +4 -0
- data/README.md +77 -0
- data/Rakefile +18 -3
- data/examples/rubygems.rb +2 -2
- data/lib/mechanize.rb +3 -2
- data/lib/mechanize/chunked_termination_error.rb +1 -0
- data/lib/mechanize/content_type_error.rb +1 -0
- data/lib/mechanize/cookie.rb +1 -13
- data/lib/mechanize/cookie_jar.rb +4 -12
- data/lib/mechanize/directory_saver.rb +1 -0
- data/lib/mechanize/download.rb +2 -1
- data/lib/mechanize/element_matcher.rb +1 -0
- data/lib/mechanize/element_not_found_error.rb +1 -0
- data/lib/mechanize/file.rb +2 -1
- data/lib/mechanize/file_connection.rb +5 -3
- data/lib/mechanize/file_request.rb +1 -0
- data/lib/mechanize/file_response.rb +4 -1
- data/lib/mechanize/file_saver.rb +1 -0
- data/lib/mechanize/form.rb +2 -10
- data/lib/mechanize/form/button.rb +1 -0
- data/lib/mechanize/form/check_box.rb +1 -0
- data/lib/mechanize/form/field.rb +1 -0
- data/lib/mechanize/form/file_upload.rb +1 -0
- data/lib/mechanize/form/hidden.rb +1 -0
- data/lib/mechanize/form/image_button.rb +1 -0
- data/lib/mechanize/form/keygen.rb +1 -0
- data/lib/mechanize/form/multi_select_list.rb +1 -0
- data/lib/mechanize/form/option.rb +1 -0
- data/lib/mechanize/form/radio_button.rb +1 -0
- data/lib/mechanize/form/reset.rb +1 -0
- data/lib/mechanize/form/select_list.rb +1 -0
- data/lib/mechanize/form/submit.rb +1 -0
- data/lib/mechanize/form/text.rb +1 -0
- data/lib/mechanize/form/textarea.rb +1 -0
- data/lib/mechanize/headers.rb +1 -0
- data/lib/mechanize/history.rb +1 -0
- data/lib/mechanize/http.rb +1 -0
- data/lib/mechanize/http/agent.rb +16 -8
- data/lib/mechanize/http/auth_challenge.rb +1 -0
- data/lib/mechanize/http/auth_realm.rb +1 -0
- data/lib/mechanize/http/auth_store.rb +1 -0
- data/lib/mechanize/http/content_disposition_parser.rb +14 -2
- data/lib/mechanize/http/www_authenticate_parser.rb +3 -3
- data/lib/mechanize/image.rb +1 -0
- data/lib/mechanize/page.rb +4 -3
- data/lib/mechanize/page/base.rb +1 -0
- data/lib/mechanize/page/frame.rb +1 -0
- data/lib/mechanize/page/image.rb +1 -0
- data/lib/mechanize/page/label.rb +1 -0
- data/lib/mechanize/page/link.rb +8 -1
- data/lib/mechanize/page/meta_refresh.rb +1 -0
- data/lib/mechanize/parser.rb +1 -0
- data/lib/mechanize/pluggable_parsers.rb +1 -0
- data/lib/mechanize/prependable.rb +1 -0
- data/lib/mechanize/redirect_limit_reached_error.rb +1 -0
- data/lib/mechanize/redirect_not_get_or_head_error.rb +1 -0
- data/lib/mechanize/response_code_error.rb +2 -1
- data/lib/mechanize/response_read_error.rb +1 -0
- data/lib/mechanize/robots_disallowed_error.rb +1 -0
- data/lib/mechanize/test_case.rb +34 -29
- data/lib/mechanize/test_case/bad_chunking_servlet.rb +1 -0
- data/lib/mechanize/test_case/basic_auth_servlet.rb +1 -0
- data/lib/mechanize/test_case/content_type_servlet.rb +1 -0
- data/lib/mechanize/test_case/digest_auth_servlet.rb +1 -0
- data/lib/mechanize/test_case/file_upload_servlet.rb +1 -0
- data/lib/mechanize/test_case/form_servlet.rb +1 -0
- data/lib/mechanize/test_case/gzip_servlet.rb +4 -3
- data/lib/mechanize/test_case/header_servlet.rb +1 -0
- data/lib/mechanize/test_case/http_refresh_servlet.rb +1 -0
- data/lib/mechanize/test_case/infinite_redirect_servlet.rb +1 -0
- data/lib/mechanize/test_case/infinite_refresh_servlet.rb +1 -0
- data/lib/mechanize/test_case/many_cookies_as_string_servlet.rb +1 -0
- data/lib/mechanize/test_case/many_cookies_servlet.rb +1 -0
- data/lib/mechanize/test_case/modified_since_servlet.rb +1 -0
- data/lib/mechanize/test_case/ntlm_servlet.rb +1 -0
- data/lib/mechanize/test_case/one_cookie_no_spaces_servlet.rb +1 -0
- data/lib/mechanize/test_case/one_cookie_servlet.rb +1 -0
- data/lib/mechanize/test_case/quoted_value_cookie_servlet.rb +1 -0
- data/lib/mechanize/test_case/redirect_servlet.rb +1 -0
- data/lib/mechanize/test_case/referer_servlet.rb +1 -0
- data/lib/mechanize/test_case/refresh_with_empty_url.rb +1 -0
- data/lib/mechanize/test_case/refresh_without_url.rb +1 -0
- data/lib/mechanize/test_case/response_code_servlet.rb +1 -0
- data/lib/mechanize/test_case/robots_txt_servlet.rb +1 -0
- data/lib/mechanize/test_case/send_cookies_servlet.rb +1 -0
- data/lib/mechanize/test_case/server.rb +1 -0
- data/lib/mechanize/test_case/servlets.rb +1 -0
- data/lib/mechanize/test_case/verb_servlet.rb +5 -6
- data/lib/mechanize/unauthorized_error.rb +1 -0
- data/lib/mechanize/unsupported_scheme_error.rb +1 -0
- data/lib/mechanize/util.rb +2 -1
- data/lib/mechanize/version.rb +2 -1
- data/lib/mechanize/xml_file.rb +1 -0
- data/mechanize.gemspec +45 -35
- data/test/htdocs/dir with spaces/foo.html +1 -0
- data/test/htdocs/tc_links.html +1 -1
- data/test/test_mechanize.rb +19 -7
- data/test/test_mechanize_cookie.rb +19 -19
- data/test/test_mechanize_cookie_jar.rb +85 -53
- data/test/test_mechanize_download.rb +13 -1
- data/test/test_mechanize_file.rb +10 -0
- data/test/test_mechanize_file_connection.rb +21 -3
- data/test/test_mechanize_file_response.rb +25 -1
- data/test/test_mechanize_form.rb +12 -0
- data/test/test_mechanize_form_keygen.rb +1 -0
- data/test/test_mechanize_http_agent.rb +53 -8
- data/test/test_mechanize_http_content_disposition_parser.rb +27 -0
- data/test/test_mechanize_link.rb +24 -0
- data/test/test_mechanize_page_encoding.rb +28 -1
- metadata +117 -71
- data/.travis.yml +0 -36
- data/README.rdoc +0 -77
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mechanize/test_case'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
class TestMechanizeCookieJar < Mechanize::TestCase
|
4
5
|
|
@@ -39,23 +40,23 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
39
40
|
:path => '/',
|
40
41
|
:expires => Time.now + (10 * 86400),
|
41
42
|
:for_domain => true,
|
42
|
-
:domain => '
|
43
|
+
:domain => 'rubygems.org'
|
43
44
|
}.merge(options)
|
44
45
|
end
|
45
46
|
|
46
47
|
def test_two_cookies_same_domain_and_name_different_paths
|
47
|
-
url = URI 'http://
|
48
|
+
url = URI 'http://rubygems.org/'
|
48
49
|
|
49
50
|
cookie = Mechanize::Cookie.new(cookie_values)
|
50
51
|
@jar.add(url, cookie)
|
51
52
|
@jar.add(url, Mechanize::Cookie.new(cookie_values(:path => '/onetwo')))
|
52
53
|
|
53
54
|
assert_equal(1, @jar.cookies(url).length)
|
54
|
-
assert_equal 2, @jar.cookies(URI('http://
|
55
|
+
assert_equal 2, @jar.cookies(URI('http://rubygems.org/onetwo')).length
|
55
56
|
end
|
56
57
|
|
57
58
|
def test_domain_case
|
58
|
-
url = URI 'http://
|
59
|
+
url = URI 'http://rubygems.org/'
|
59
60
|
|
60
61
|
# Add one cookie with an expiration date in the future
|
61
62
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -63,49 +64,49 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
63
64
|
assert_equal(1, @jar.cookies(url).length)
|
64
65
|
|
65
66
|
@jar.add(url, Mechanize::Cookie.new(
|
66
|
-
cookie_values(:domain => '
|
67
|
+
cookie_values(:domain => 'rubygems.Org', :name => 'aaron')))
|
67
68
|
|
68
69
|
assert_equal(2, @jar.cookies(url).length)
|
69
70
|
|
70
|
-
url2 = URI 'http://
|
71
|
+
url2 = URI 'http://rubygems.oRg/'
|
71
72
|
assert_equal(2, @jar.cookies(url2).length)
|
72
73
|
end
|
73
74
|
|
74
75
|
def test_host_only
|
75
|
-
url = URI.parse('http://
|
76
|
+
url = URI.parse('http://rubygems.org/')
|
76
77
|
|
77
78
|
@jar.add(url, Mechanize::Cookie.new(
|
78
|
-
cookie_values(:domain => '
|
79
|
+
cookie_values(:domain => 'rubygems.org', :for_domain => false)))
|
79
80
|
|
80
81
|
assert_equal(1, @jar.cookies(url).length)
|
81
82
|
|
82
|
-
assert_equal(1, @jar.cookies(URI('http://
|
83
|
+
assert_equal(1, @jar.cookies(URI('http://rubygems.org/')).length)
|
83
84
|
|
84
|
-
assert_equal(1, @jar.cookies(URI('https://
|
85
|
+
assert_equal(1, @jar.cookies(URI('https://rubygems.org/')).length)
|
85
86
|
|
86
|
-
assert_equal(0, @jar.cookies(URI('http://www.
|
87
|
+
assert_equal(0, @jar.cookies(URI('http://www.rubygems.org/')).length)
|
87
88
|
end
|
88
89
|
|
89
90
|
def test_empty_value
|
90
91
|
values = cookie_values(:value => "")
|
91
|
-
url = URI 'http://
|
92
|
+
url = URI 'http://rubygems.org/'
|
92
93
|
|
93
94
|
# Add one cookie with an expiration date in the future
|
94
95
|
cookie = Mechanize::Cookie.new(values)
|
95
96
|
@jar.add(url, cookie)
|
96
97
|
assert_equal(1, @jar.cookies(url).length)
|
97
98
|
|
98
|
-
@jar.add url, Mechanize::Cookie.new(values.merge(:domain => '
|
99
|
+
@jar.add url, Mechanize::Cookie.new(values.merge(:domain => 'rubygems.Org',
|
99
100
|
:name => 'aaron'))
|
100
101
|
|
101
102
|
assert_equal(2, @jar.cookies(url).length)
|
102
103
|
|
103
|
-
url2 = URI 'http://
|
104
|
+
url2 = URI 'http://rubygems.oRg/'
|
104
105
|
assert_equal(2, @jar.cookies(url2).length)
|
105
106
|
end
|
106
107
|
|
107
108
|
def test_add_future_cookies
|
108
|
-
url = URI 'http://
|
109
|
+
url = URI 'http://rubygems.org/'
|
109
110
|
|
110
111
|
# Add one cookie with an expiration date in the future
|
111
112
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -117,14 +118,14 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
117
118
|
assert_equal(1, @jar.cookies(url).length)
|
118
119
|
|
119
120
|
# Make sure we can get the cookie from different paths
|
120
|
-
assert_equal(1, @jar.cookies(URI('http://
|
121
|
+
assert_equal(1, @jar.cookies(URI('http://rubygems.org/login')).length)
|
121
122
|
|
122
123
|
# Make sure we can't get the cookie from different domains
|
123
124
|
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
|
124
125
|
end
|
125
126
|
|
126
127
|
def test_add_multiple_cookies
|
127
|
-
url = URI 'http://
|
128
|
+
url = URI 'http://rubygems.org/'
|
128
129
|
|
129
130
|
# Add one cookie with an expiration date in the future
|
130
131
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -136,14 +137,14 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
136
137
|
assert_equal(2, @jar.cookies(url).length)
|
137
138
|
|
138
139
|
# Make sure we can get the cookie from different paths
|
139
|
-
assert_equal(2, @jar.cookies(URI('http://
|
140
|
+
assert_equal(2, @jar.cookies(URI('http://rubygems.org/login')).length)
|
140
141
|
|
141
142
|
# Make sure we can't get the cookie from different domains
|
142
143
|
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
|
143
144
|
end
|
144
145
|
|
145
146
|
def test_add_rejects_cookies_that_do_not_contain_an_embedded_dot
|
146
|
-
url = URI 'http://
|
147
|
+
url = URI 'http://rubygems.org/'
|
147
148
|
|
148
149
|
tld_cookie = Mechanize::Cookie.new(cookie_values(:domain => '.org'))
|
149
150
|
@jar.add(url, tld_cookie)
|
@@ -196,43 +197,43 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
196
197
|
end
|
197
198
|
|
198
199
|
def test_cookie_without_leading_dot_does_not_cause_substring_match
|
199
|
-
url = URI 'http://
|
200
|
+
url = URI 'http://arubygems.org/'
|
200
201
|
|
201
|
-
cookie = Mechanize::Cookie.new(cookie_values(:domain => '
|
202
|
+
cookie = Mechanize::Cookie.new(cookie_values(:domain => 'rubygems.org'))
|
202
203
|
@jar.add(url, cookie)
|
203
204
|
|
204
205
|
assert_equal(0, @jar.cookies(url).length)
|
205
206
|
end
|
206
207
|
|
207
208
|
def test_cookie_without_leading_dot_matches_subdomains
|
208
|
-
url = URI 'http://admin.
|
209
|
+
url = URI 'http://admin.rubygems.org/'
|
209
210
|
|
210
|
-
cookie = Mechanize::Cookie.new(cookie_values(:domain => '
|
211
|
+
cookie = Mechanize::Cookie.new(cookie_values(:domain => 'rubygems.org'))
|
211
212
|
@jar.add(url, cookie)
|
212
213
|
|
213
214
|
assert_equal(1, @jar.cookies(url).length)
|
214
215
|
end
|
215
216
|
|
216
217
|
def test_cookies_with_leading_dot_match_subdomains
|
217
|
-
url = URI 'http://admin.
|
218
|
+
url = URI 'http://admin.rubygems.org/'
|
218
219
|
|
219
|
-
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.
|
220
|
+
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubygems.org')))
|
220
221
|
|
221
222
|
assert_equal(1, @jar.cookies(url).length)
|
222
223
|
end
|
223
224
|
|
224
225
|
def test_cookies_with_leading_dot_match_parent_domains
|
225
|
-
url = URI 'http://
|
226
|
+
url = URI 'http://rubygems.org/'
|
226
227
|
|
227
|
-
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.
|
228
|
+
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubygems.org')))
|
228
229
|
|
229
230
|
assert_equal(1, @jar.cookies(url).length)
|
230
231
|
end
|
231
232
|
|
232
233
|
def test_cookies_with_leading_dot_match_parent_domains_exactly
|
233
|
-
url = URI 'http://
|
234
|
+
url = URI 'http://arubygems.org/'
|
234
235
|
|
235
|
-
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.
|
236
|
+
@jar.add(url, Mechanize::Cookie.new(cookie_values(:domain => '.rubygems.org')))
|
236
237
|
|
237
238
|
assert_equal(0, @jar.cookies(url).length)
|
238
239
|
end
|
@@ -275,7 +276,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
275
276
|
end
|
276
277
|
|
277
278
|
def test_clear_bang
|
278
|
-
url = URI 'http://
|
279
|
+
url = URI 'http://rubygems.org/'
|
279
280
|
|
280
281
|
# Add one cookie with an expiration date in the future
|
281
282
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -289,7 +290,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
289
290
|
end
|
290
291
|
|
291
292
|
def test_save_cookies_yaml
|
292
|
-
url = URI 'http://
|
293
|
+
url = URI 'http://rubygems.org/'
|
293
294
|
|
294
295
|
# Add one cookie with an expiration date in the future
|
295
296
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -315,7 +316,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
315
316
|
end
|
316
317
|
|
317
318
|
def test_save_session_cookies_yaml
|
318
|
-
url = URI 'http://
|
319
|
+
url = URI 'http://rubygems.org/'
|
319
320
|
|
320
321
|
# Add one cookie with an expiration date in the future
|
321
322
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -341,7 +342,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
341
342
|
|
342
343
|
|
343
344
|
def test_save_cookies_cookiestxt
|
344
|
-
url = URI 'http://
|
345
|
+
url = URI 'http://rubygems.org/'
|
345
346
|
|
346
347
|
# Add one cookie with an expiration date in the future
|
347
348
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -378,7 +379,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
378
379
|
end
|
379
380
|
|
380
381
|
def test_expire_cookies
|
381
|
-
url = URI 'http://
|
382
|
+
url = URI 'http://rubygems.org/'
|
382
383
|
|
383
384
|
# Add one cookie with an expiration date in the future
|
384
385
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -390,7 +391,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
390
391
|
assert_equal(2, @jar.cookies(url).length)
|
391
392
|
|
392
393
|
# Make sure we can get the cookie from different paths
|
393
|
-
assert_equal(2, @jar.cookies(URI('http://
|
394
|
+
assert_equal(2, @jar.cookies(URI('http://rubygems.org/login')).length)
|
394
395
|
|
395
396
|
# Expire the first cookie
|
396
397
|
@jar.add(url, Mechanize::Cookie.new(
|
@@ -405,7 +406,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
405
406
|
|
406
407
|
def test_session_cookies
|
407
408
|
values = cookie_values(:expires => nil)
|
408
|
-
url = URI 'http://
|
409
|
+
url = URI 'http://rubygems.org/'
|
409
410
|
|
410
411
|
# Add one cookie with an expiration date in the future
|
411
412
|
cookie = Mechanize::Cookie.new(values)
|
@@ -417,7 +418,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
417
418
|
assert_equal(2, @jar.cookies(url).length)
|
418
419
|
|
419
420
|
# Make sure we can get the cookie from different paths
|
420
|
-
assert_equal(2, @jar.cookies(URI('http://
|
421
|
+
assert_equal(2, @jar.cookies(URI('http://rubygems.org/login')).length)
|
421
422
|
|
422
423
|
# Expire the first cookie
|
423
424
|
@jar.add(url, Mechanize::Cookie.new(values.merge(:expires => Time.now - (10 * 86400))))
|
@@ -430,7 +431,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
430
431
|
|
431
432
|
# When given a URI with a blank path, CookieJar#cookies should return
|
432
433
|
# cookies with the path '/':
|
433
|
-
url = URI 'http://
|
434
|
+
url = URI 'http://rubygems.org'
|
434
435
|
assert_equal '', url.path
|
435
436
|
assert_equal(0, @jar.cookies(url).length)
|
436
437
|
# Now add a cookie with the path set to '/':
|
@@ -441,7 +442,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
441
442
|
|
442
443
|
def test_paths
|
443
444
|
values = cookie_values(:path => "/login", :expires => nil)
|
444
|
-
url = URI 'http://
|
445
|
+
url = URI 'http://rubygems.org/login'
|
445
446
|
|
446
447
|
# Add one cookie with an expiration date in the future
|
447
448
|
cookie = Mechanize::Cookie.new(values)
|
@@ -453,8 +454,8 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
453
454
|
assert_equal(2, @jar.cookies(url).length)
|
454
455
|
|
455
456
|
# Make sure we don't get the cookie in a different path
|
456
|
-
assert_equal(0, @jar.cookies(URI('http://
|
457
|
-
assert_equal(0, @jar.cookies(URI('http://
|
457
|
+
assert_equal(0, @jar.cookies(URI('http://rubygems.org/hello')).length)
|
458
|
+
assert_equal(0, @jar.cookies(URI('http://rubygems.org/')).length)
|
458
459
|
|
459
460
|
# Expire the first cookie
|
460
461
|
@jar.add(url, Mechanize::Cookie.new(values.merge( :expires => Time.now - (10 * 86400))))
|
@@ -467,7 +468,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
467
468
|
end
|
468
469
|
|
469
470
|
def test_save_and_read_cookiestxt
|
470
|
-
url = URI 'http://
|
471
|
+
url = URI 'http://rubygems.org/'
|
471
472
|
|
472
473
|
# Add one cookie with an expiration date in the future
|
473
474
|
cookie = Mechanize::Cookie.new(cookie_values)
|
@@ -486,7 +487,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
486
487
|
end
|
487
488
|
|
488
489
|
def test_save_and_read_cookiestxt_with_session_cookies
|
489
|
-
url = URI 'http://
|
490
|
+
url = URI 'http://rubygems.org/'
|
490
491
|
|
491
492
|
@jar.add(url, Mechanize::Cookie.new(cookie_values(:expires => nil)))
|
492
493
|
|
@@ -500,10 +501,41 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
500
501
|
assert_equal(0, @jar.cookies(url).length)
|
501
502
|
end
|
502
503
|
|
504
|
+
def test_prevent_command_injection_when_saving
|
505
|
+
skip if windows?
|
506
|
+
url = URI 'http://rubygems.org/'
|
507
|
+
path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\''
|
508
|
+
|
509
|
+
@jar.add(url, Mechanize::Cookie.new(cookie_values))
|
510
|
+
|
511
|
+
in_tmpdir do
|
512
|
+
@jar.save_as(path, :cookiestxt)
|
513
|
+
assert_equal(false, File.exist?('vul.txt'))
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def test_prevent_command_injection_when_loading
|
518
|
+
skip if windows?
|
519
|
+
url = URI 'http://rubygems.org/'
|
520
|
+
path = '| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\''
|
521
|
+
|
522
|
+
@jar.add(url, Mechanize::Cookie.new(cookie_values))
|
523
|
+
|
524
|
+
in_tmpdir do
|
525
|
+
@jar.save_as("cookies.txt", :cookiestxt)
|
526
|
+
@jar.clear!
|
527
|
+
|
528
|
+
assert_raises Errno::ENOENT do
|
529
|
+
@jar.load(path, :cookiestxt)
|
530
|
+
end
|
531
|
+
assert_equal(false, File.exist?('vul.txt'))
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
503
535
|
def test_save_and_read_expired_cookies
|
504
|
-
url = URI 'http://
|
536
|
+
url = URI 'http://rubygems.org/'
|
505
537
|
|
506
|
-
@jar.jar['
|
538
|
+
@jar.jar['rubygems.org'] = {}
|
507
539
|
|
508
540
|
|
509
541
|
@jar.add url, Mechanize::Cookie.new(cookie_values)
|
@@ -515,7 +547,7 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
515
547
|
# thanks to michal "ocher" ochman for reporting the bug responsible for this test.
|
516
548
|
values = cookie_values(:expires => nil)
|
517
549
|
values_ssl = values.merge(:name => 'Baz', :domain => "#{values[:domain]}:443")
|
518
|
-
url = URI 'https://
|
550
|
+
url = URI 'https://rubygems.org/login'
|
519
551
|
|
520
552
|
cookie = Mechanize::Cookie.new(values)
|
521
553
|
@jar.add(url, cookie)
|
@@ -527,8 +559,8 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
527
559
|
end
|
528
560
|
|
529
561
|
def test_secure_cookie
|
530
|
-
nurl = URI 'http://
|
531
|
-
surl = URI 'https://
|
562
|
+
nurl = URI 'http://rubygems.org/login'
|
563
|
+
surl = URI 'https://rubygems.org/login'
|
532
564
|
|
533
565
|
ncookie = Mechanize::Cookie.new(cookie_values(:name => 'Foo1'))
|
534
566
|
scookie = Mechanize::Cookie.new(cookie_values(:name => 'Foo2', :secure => true))
|
@@ -543,10 +575,10 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
543
575
|
end
|
544
576
|
|
545
577
|
def test_save_cookies_cookiestxt_subdomain
|
546
|
-
top_url = URI 'http://
|
547
|
-
subdomain_url = URI 'http://admin.
|
578
|
+
top_url = URI 'http://rubygems.org/'
|
579
|
+
subdomain_url = URI 'http://admin.rubygems.org/'
|
548
580
|
|
549
|
-
# cookie1 is for *.
|
581
|
+
# cookie1 is for *.rubygems.org; cookie2 is only for rubygems.org, no subdomains
|
550
582
|
cookie1 = Mechanize::Cookie.new(cookie_values)
|
551
583
|
cookie2 = Mechanize::Cookie.new(cookie_values(:name => 'Boo', :for_domain => false))
|
552
584
|
|
@@ -572,8 +604,8 @@ class TestMechanizeCookieJar < Mechanize::TestCase
|
|
572
604
|
# * Cookies that match subdomains may have a leading dot, and must have
|
573
605
|
# TRUE as the second field.
|
574
606
|
cookies_txt = File.readlines("cookies.txt")
|
575
|
-
assert_equal(1, cookies_txt.grep( /^
|
576
|
-
assert_equal(1, cookies_txt.grep( /^\.
|
607
|
+
assert_equal(1, cookies_txt.grep( /^rubygems\.org\tFALSE/ ).length)
|
608
|
+
assert_equal(1, cookies_txt.grep( /^\.rubygems\.org\tTRUE/ ).length)
|
577
609
|
end
|
578
610
|
|
579
611
|
assert_equal(2, @jar.cookies(top_url).length)
|
@@ -46,6 +46,19 @@ class TestMechanizeDownload < Mechanize::TestCase
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_save_bang_does_not_allow_command_injection
|
50
|
+
skip if windows?
|
51
|
+
uri = URI.parse 'http://example/foo.html'
|
52
|
+
body_io = StringIO.new '0123456789'
|
53
|
+
|
54
|
+
download = @parser.new uri, nil, body_io
|
55
|
+
|
56
|
+
in_tmpdir do
|
57
|
+
download.save!('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
|
58
|
+
refute_operator(File, :exist?, "vul.txt")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
49
62
|
def test_save_tempfile
|
50
63
|
uri = URI.parse 'http://example/foo.html'
|
51
64
|
Tempfile.open @NAME do |body_io|
|
@@ -84,6 +97,5 @@ class TestMechanizeDownload < Mechanize::TestCase
|
|
84
97
|
|
85
98
|
assert_equal "foo.html", download.filename
|
86
99
|
end
|
87
|
-
|
88
100
|
end
|
89
101
|
|
data/test/test_mechanize_file.rb
CHANGED
@@ -103,5 +103,15 @@ class TestMechanizeFile < Mechanize::TestCase
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
def test_save_bang_does_not_allow_command_injection
|
107
|
+
skip if windows?
|
108
|
+
uri = URI 'http://example/test.html'
|
109
|
+
page = Mechanize::File.new uri, nil, ''
|
110
|
+
|
111
|
+
in_tmpdir do
|
112
|
+
page.save!('| ruby -rfileutils -e \'FileUtils.touch("vul.txt")\'')
|
113
|
+
refute_operator(File, :exist?, "vul.txt")
|
114
|
+
end
|
115
|
+
end
|
106
116
|
end
|
107
117
|
|
@@ -3,19 +3,37 @@ require 'mechanize/test_case'
|
|
3
3
|
class TestMechanizeFileConnection < Mechanize::TestCase
|
4
4
|
|
5
5
|
def test_request
|
6
|
-
|
6
|
+
file_path = File.expand_path(__FILE__)
|
7
|
+
uri = URI.parse "file://#{file_path}"
|
7
8
|
conn = Mechanize::FileConnection.new
|
8
9
|
|
9
10
|
body = ''
|
10
11
|
|
11
12
|
conn.request uri, nil do |response|
|
13
|
+
assert_equal(file_path, response.file_path)
|
12
14
|
response.read_body do |part|
|
13
15
|
body << part
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
assert_equal File.read(__FILE__), body
|
19
|
+
assert_equal File.read(__FILE__), body.gsub(/\r\n/, "\n")
|
18
20
|
end
|
19
21
|
|
20
|
-
|
22
|
+
def test_request_on_uri_with_windows_drive
|
23
|
+
uri_string = "file://C:/path/to/file.html"
|
24
|
+
expected_file_path = "C:/path/to/file.html"
|
25
|
+
|
26
|
+
uri = URI.parse(uri_string)
|
27
|
+
conn = Mechanize::FileConnection.new
|
21
28
|
|
29
|
+
called = false
|
30
|
+
yielded_file_path = nil
|
31
|
+
conn.request(uri, nil) do |response|
|
32
|
+
called = true
|
33
|
+
yielded_file_path = response.file_path
|
34
|
+
end
|
35
|
+
|
36
|
+
assert(called)
|
37
|
+
assert_equal(expected_file_path, yielded_file_path)
|
38
|
+
end
|
39
|
+
end
|