lanyon 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1d734e248758a22e846cf73dc15b13a323548a6
4
- data.tar.gz: b7f4ed547b531a6d746f5a0caf31928af6ad968e
3
+ metadata.gz: 3ba71c4bb36491071c4f3918250373339f2b06fe
4
+ data.tar.gz: 77bf257ad911b6e56e1420a7c2443b61b1e149df
5
5
  SHA512:
6
- metadata.gz: 36f129ec0ff9053464adcfaec6984d10eb04d6d9252538ab4f434ed0fd2de5aeaa3348d68507eb0b906b3664a44d526bd333668ae0a1757f24f526796850106b
7
- data.tar.gz: 33a2dc54b3b19c0108773903e18d525808875dcce69f98abf725b5f4fe7bc3cc52f97b0d2d61bffce8c89186495bf24cce627c392a4e6b06c97a626f6b96e960
6
+ metadata.gz: 2595d1de19d7f28071efdc3288708089ad6d316ae16406174197eb02c35ad8ff7cc1d113cc99247070179c8bb7ab1eb64571623618c295778fcf820b1c342b0e
7
+ data.tar.gz: 8f8870aba29ea1fe713f93ef87b633965288a747e210297925bd420833c368b804640603bc06f3c8f80ad7f32b3d0cee82becfd3f084b7ac1cb5d079ee530f42
@@ -41,7 +41,7 @@ module Lanyon
41
41
  private
42
42
 
43
43
  def response(filename) # :nodoc:
44
- response = Rack::Response.new(File.read(filename))
44
+ response = Rack::Response.new(File.binread(filename))
45
45
  response["Content-Type"] = media_type(filename)
46
46
  response["Last-Modified"] = modification_time(filename)
47
47
 
data/lib/lanyon/router.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "rack/utils"
2
+
3
+
1
4
  module Lanyon
2
5
 
3
6
  # Router class for Lanyon applications.
@@ -17,17 +20,12 @@ module Lanyon
17
20
  # - +:must_redirect+ if the request must be redirected to <tt>path/</tt>.
18
21
  #
19
22
  def endpoint(path)
20
- fullpath = File.join(@root, path)
21
-
22
- if fullpath.end_with?("/")
23
- normalized = fullpath + "index.html"
24
- else
25
- normalized = fullpath
26
- end
23
+ normalized = normalize_path_info(path)
27
24
 
28
- endpoint = if FileTest.file?(normalized)
29
- normalized
30
- elsif needs_redirect_to_dir?(normalized)
25
+ fullpath = File.join(@root, normalized)
26
+ endpoint = if FileTest.file?(fullpath)
27
+ fullpath
28
+ elsif needs_redirect_to_dir?(fullpath)
31
29
  :must_redirect
32
30
  else
33
31
  :not_found
@@ -40,7 +38,7 @@ module Lanyon
40
38
  def custom_404_body
41
39
  filename = File.join(root, "404.html")
42
40
 
43
- File.exist?(filename) ? File.read(filename) : nil
41
+ File.exist?(filename) ? File.binread(filename) : nil
44
42
  end
45
43
 
46
44
  private
@@ -48,5 +46,15 @@ module Lanyon
48
46
  def needs_redirect_to_dir?(fullpath) # :nodoc:
49
47
  !fullpath.end_with?("/") && FileTest.file?(fullpath + "/index.html")
50
48
  end
49
+
50
+ def normalize_path_info(path)
51
+ if path.end_with?("/")
52
+ normalized = path + "index.html"
53
+ else
54
+ normalized = path
55
+ end
56
+
57
+ Rack::Utils.clean_path_info(normalized)
58
+ end
51
59
  end
52
60
  end
@@ -1,4 +1,4 @@
1
1
  module Lanyon
2
- VERSION = '0.2.0'
3
- DATE = '2015-11-11'
2
+ VERSION = '0.2.2'
3
+ DATE = '2015-12-06'
4
4
  end
data/lib/lanyon.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  # See Lanyon module for documentation.
4
4
 
5
5
  require "jekyll"
6
+ require "rack"
6
7
 
7
8
  require "lanyon/application"
8
9
  require "lanyon/router"
@@ -18,7 +19,8 @@ require "lanyon/version"
18
19
  #
19
20
  module Lanyon
20
21
 
21
- # Builds the Jekyll site and returns a Rack application.
22
+ # Builds the Jekyll site, prepares the middleware stack,
23
+ # and returns the Rack application.
22
24
  #
23
25
  # Options:
24
26
  #
@@ -38,7 +40,7 @@ module Lanyon
38
40
  if skip_build
39
41
  puts skip_build_warning
40
42
  else
41
- build(config)
43
+ process(config)
42
44
  end
43
45
 
44
46
  destination = config["destination"]
@@ -71,7 +73,11 @@ module Lanyon
71
73
  end
72
74
 
73
75
  # @private
74
- def self.build(config) # :nodoc:
76
+ #
77
+ # Wraps Jekyll::Site's process method that builds the site.
78
+ #
79
+ # Takes a Jekyll configuration hash as argument.
80
+ def self.process(config) # :nodoc:
75
81
  site = ::Jekyll::Site.new(config)
76
82
  puts "Generating site: #{site.source} -> #{site.dest}"
77
83
  site.process
@@ -0,0 +1,4 @@
1
+ File
2
+ with
3
+ CRLF
4
+ newlines
@@ -177,6 +177,18 @@ describe "when handling requests" do
177
177
  end
178
178
 
179
179
 
180
+ describe "when asked for paths with directory traversal" do
181
+
182
+ it "returns status 404 for unsafe directory traversal" do
183
+ filename = File.join(@destdir, "/../_site/index.html")
184
+ assert File.exist?(filename)
185
+
186
+ @response = @request.get("/../_site/index.html")
187
+ @response.status.must_equal 404
188
+ end
189
+ end
190
+
191
+
180
192
  describe "when a directory is requested" do
181
193
 
182
194
  it "redirects to 'directory/' for 'directory' with index.html" do
@@ -233,7 +245,8 @@ describe "when handling requests" do
233
245
  end
234
246
 
235
247
  it "returns correct body" do
236
- @response.body.must_match %r{<p>¡Buenos días!</p>}
248
+ response_body = @response.body.force_encoding("UTF-8")
249
+ response_body.must_match %r{<p>¡Buenos días!</p>}
237
250
  end
238
251
 
239
252
  it "returns the bytesize as Content-Length header" do
@@ -242,6 +255,23 @@ describe "when handling requests" do
242
255
  end
243
256
 
244
257
 
258
+ describe "when resource contains CRLF newlines" do
259
+
260
+ before do
261
+ @response = @request.get("/crlf.dat")
262
+ end
263
+
264
+ it "returns correct body" do
265
+ expected = "File\r\nwith\r\nCRLF\r\nnewlines\r\n"
266
+ @response.body.must_equal expected
267
+ end
268
+
269
+ it "returns the bytesize as Content-Length header" do
270
+ @response.original_headers["Content-Length"].must_equal "28"
271
+ end
272
+ end
273
+
274
+
245
275
  describe "when handling If-Modified-Since requests" do
246
276
 
247
277
  before do
data/test/test_router.rb CHANGED
@@ -79,6 +79,35 @@ describe Lanyon::Router do
79
79
  end
80
80
 
81
81
 
82
+ describe "when asked for paths with directory traversal" do
83
+
84
+ it "discards leading '..' for existing path" do
85
+ filename = File.join(@sitedir, "page.html")
86
+ @router.endpoint("/../../page.html").must_equal filename
87
+ end
88
+
89
+ it "allows safe directory traversal" do
90
+ filename = File.join(@sitedir, "index.html")
91
+ @router.endpoint("/dir1/../").must_equal filename
92
+ end
93
+
94
+ it "returns :not_found for unsafe directory traversal 1" do
95
+ filename = File.join(@sitedir, "/../_site/page.html")
96
+ assert File.exist?(filename)
97
+
98
+ @router.endpoint("/../_site/page.html").must_equal :not_found
99
+ end
100
+
101
+ it "returns :not_found for unsafe directory traversal 2" do
102
+ @router.endpoint("/%2E%2E/_site/").must_equal :not_found
103
+ end
104
+
105
+ it "returns :not_found for unsafe directory traversal 3" do
106
+ @router.endpoint("/dir1/../dir1/../../_site/").must_equal :not_found
107
+ end
108
+ end
109
+
110
+
82
111
  describe "when asked for #custom_404_body" do
83
112
 
84
113
  describe "when 404.html does not exist" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lanyon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcus Stollsteimer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-11 00:00:00.000000000 Z
11
+ date: 2015-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -97,6 +97,7 @@ files:
97
97
  - test/helper.rb
98
98
  - test/source/_posts/2015-11-05-hello-world.md
99
99
  - test/source/buenos_dias.md
100
+ - test/source/crlf.dat
100
101
  - test/source/css/test.css
101
102
  - test/source/dir-with-index/index.md
102
103
  - test/source/dir-without-index/page.md