Codebase list jekyll / df17e7a
Merge branch 'upstream' into 'upstream' New upstream version 3.8.6+dfsg See merge request ruby-team/jekyll!4 Daniel Leidert 4 years ago
36 changed file(s) with 519 addition(s) and 69 deletion(s). Raw diff Collapse all Expand all
11 script: script/cibuild
22 cache: bundler
33 language: ruby
4 sudo: false
54
65 rvm:
76 - &ruby1 2.5.1
3029 only:
3130 - master
3231 - themes
33 - /*-stable/
32 - /.*-stable/
3433
3534 notifications:
3635 slack:
5352 - bundle exec codeclimate-test-reporter
5453
5554 before_install:
56 - gem update --system
57 - gem install bundler
55 - gem update --system || true
2626 gem "httpclient"
2727 gem "jekyll_test_plugin"
2828 gem "jekyll_test_plugin_malicious"
29 # nokogiri v1.8 does not work with ruby 2.1 and below
30 gem "nokogiri", RUBY_VERSION >= "2.2" ? "~> 1.7" : "~> 1.7.0"
29 # nokogiri v1.10 does not work with ruby 2.2 and below
30 gem "nokogiri", RUBY_VERSION >= "2.3" ? "~> 1.9" : "~> 1.9.0"
3131 gem "rspec"
3232 gem "rspec-mocks"
3333 gem "rubocop", "~> 0.56.0"
3434 gem "test-dependency-theme", :path => File.expand_path("test/fixtures/test-dependency-theme", __dir__)
3535 gem "test-theme", :path => File.expand_path("test/fixtures/test-theme", __dir__)
36 gem "test-theme-skinny", :path => File.expand_path("test/fixtures/test-theme-skinny", __dir__)
37 gem "test-theme-symlink", :path => File.expand_path("test/fixtures/test-theme-symlink", __dir__)
3638
37 gem "jruby-openssl" if RUBY_ENGINE == "jruby"
39 gem "jruby-openssl", "0.10.1" if RUBY_ENGINE == "jruby"
3840 end
3941
4042 #
0 ## 3.8.6 / 2019-07-02
1
2 ### Bug Fixes
3
4 * Update log output for an invalid theme directory (#7734)
5 * Memoize `SiteDrop#documents` to reduce allocations (#7722)
6 * Excerpt handling of custom and intermediate tags (#7467)
7 * Escape valid special chars in a site's path name (#7573)
8 * Revert memoizing `Site#docs_to_write` and refactor `#documents` (#7689)
9 * Fix broken `include_relative` usage in excerpt (#7690)
10 * Install platform-specific gems as required (3c06609406)
11
12 ### Security Fixes
13
14 * Theme gems: ensure directories aren't symlinks (#7424)
15
16 ## 3.8.5 / 2018-11-04
17
18 ### Bug Fixes
19
20 * Re-implement handling Liquid blocks in excerpts (#7250)
21
22 ## 3.8.4 / 2018-09-18
23
24 ### Bug Fixes
25
26 * security: fix `include` bypass of `EntryFilter#filter` symlink check (#7228)
27
028 ## 3.8.3 / 2018-06-05
129
230 ### Bug Fixes
55 only:
66 - master
77 - themes
8 - /.*-stable/
89
910 build: off
1011
00 ---
1 version: 3.8.3
1 version: 3.8.6
22 name: Jekyll • Simple, blog-aware, static sites
33 description: Transform your plain text into static websites and blogs
44 url: https://jekyllrb.com
22 permalink: "/docs/history/"
33 note: This file is autogenerated. Edit /History.markdown instead.
44 ---
5
6 ## 3.8.6 / 2019-07-02
7 {: #v3-8-6}
8
9 ### Bug Fixes
10 {: #bug-fixes-v3-8-6}
11
12 - Update log output for an invalid theme directory ([#7734]({{ site.repository }}/issues/7734))
13 - Memoize `SiteDrop#documents` to reduce allocations ([#7722]({{ site.repository }}/issues/7722))
14 - Excerpt handling of custom and intermediate tags ([#7467]({{ site.repository }}/issues/7467))
15 - Escape valid special chars in a site's path name ([#7573]({{ site.repository }}/issues/7573))
16 - Revert memoizing `Site#docs_to_write` and refactor `#documents` ([#7689]({{ site.repository }}/issues/7689))
17 - Fix broken `include_relative` usage in excerpt ([#7690]({{ site.repository }}/issues/7690))
18 - Install platform-specific gems as required (3c06609406)
19
20 ### Security Fixes
21 {: #security-fixes-v3-8-6}
22
23 - Theme gems: ensure directories aren't symlinks ([#7424]({{ site.repository }}/issues/7424))
24
25
26 ## 3.8.5 / 2018-11-04
27 {: #v3-8-5}
28
29 ### Bug Fixes
30 {: #bug-fixes-v3-8-5}
31
32 - Re-implement handling Liquid blocks in excerpts ([#7250]({{ site.repository }}/issues/7250))
33
34
35 ## 3.8.4 / 2018-09-18
36 {: #v3-8-4}
37
38 ### Bug Fixes
39 {: #bug-fixes-v3-8-4}
40
41 - security: fix `include` bypass of `EntryFilter#filter` symlink check ([#7228]({{ site.repository }}/issues/7228))
42
543
644 ## 3.8.3 / 2018-06-05
745 {: #v3-8-3}
0 ---
1 title: 'Jekyll 3.8.6 Released'
2 date: 2019-07-02 11:21:02 -0400
3 author: parkr
4 version: 3.8.6
5 categories: [release]
6 ---
7
8 We have another patch release in the 3.8 series! This time, we have one security patch
9 and a handful of bug patches, including:
10
11 - Filter symlinks from theme gems
12 - Fix excerpt handling of some Liquid tags
13 - Handle case where a theme directory doesn't exist
14 - A few internal optimizations to reduce memory overhead
15
16 ... and a few more! You can check out the patches and see all the details in [the release notes](/docs/history/#v3-8-6)
17
18 Happy Jekylling!
0 Feature: include_relative Tag
1 In order to share content across several closely related pages
2 As a hacker who likes to blog
3 I want to be able to include snippets in my site's pages and documents relative to current file
4
5 Scenario: Include a file relative to a post
6 Given I have a _posts directory
7 And I have a _posts/snippets directory
8 And I have the following post:
9 | title | date | content |
10 | Star Wars | 2018-09-02 | {% include_relative snippets/welcome_para.md %} |
11 And I have an "_posts/snippets/welcome_para.md" file that contains "Welcome back Dear Reader!"
12 When I run jekyll build
13 Then I should get a zero exit status
14 And the _site directory should exist
15 And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
16
17 Scenario: Include a nested file relative to a post
18 Given I have a _posts directory
19 And I have a _posts/snippets directory
20 And I have a _posts/snippets/welcome_para directory
21 And I have the following post:
22 | title | date | content |
23 | Star Wars | 2018-09-02 | {% include_relative snippets/welcome_para.md %} |
24 And I have an "_posts/snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
25 And I have an "_posts/snippets/welcome_para/greeting.md" file that contains "Welcome back"
26 When I run jekyll build
27 Then I should get a zero exit status
28 And the _site directory should exist
29 And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
30
31 Scenario: Include a nested file relative to a post as an excerpt
32 Given I have a _posts directory
33 And I have a _posts/snippets directory
34 And I have a _posts/snippets/welcome_para directory
35 And I have a "_posts/2018-09-02-star-wars.md" file with content:
36 """
37 {% include_relative snippets/welcome_para.md %}
38
39 Hello World
40 """
41 And I have an "_posts/snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
42 And I have an "_posts/snippets/welcome_para/greeting.md" file that contains "Welcome back"
43 And I have an "index.md" page that contains "{% for post in site.posts %}{{ post.excerpt }}{% endfor %}"
44 When I run jekyll build
45 Then I should get a zero exit status
46 And the _site directory should exist
47 And I should see "Welcome back Dear Reader!" in "_site/2018/09/02/star-wars.html"
48 And I should see "Welcome back Dear Reader!" in "_site/index.html"
49
50 Scenario: Include a nested file relative to a page at root
51 Given I have a snippets directory
52 And I have a snippets/welcome_para directory
53 And I have a "index.md" page that contains "{% include_relative snippets/welcome_para.md %}"
54 And I have a "snippets/welcome_para.md" file that contains "{% include_relative snippets/welcome_para/greeting.md %} Dear Reader!"
55 And I have a "snippets/welcome_para/greeting.md" file that contains "Welcome back"
56 When I run jekyll build
57 Then I should get a zero exit status
58 And the _site directory should exist
59 And I should see "Welcome back Dear Reader!" in "_site/index.html"
33 In order to share my awesome ideas with the interwebs
44 But I want to make it as simply as possible
55 So render with Liquid and place in Layouts
6
7 Scenario: Rendering a site with parentheses in its path name
8 Given I have a blank site in "omega(beta)"
9 And I have an "omega(beta)/test.md" page with layout "simple" that contains "Hello World"
10 And I have an omega(beta)/_includes directory
11 And I have an "omega(beta)/_includes/head.html" file that contains "Snippet"
12 And I have a configuration file with "source" set to "omega(beta)"
13 And I have an omega(beta)/_layouts directory
14 And I have an "omega(beta)/_layouts/simple.html" file that contains "{% include head.html %}: {{ content }}"
15 When I run jekyll build --profile
16 Then I should get a zero exit status
17 And I should see "Snippet: <p>Hello World</p>" in "_site/test.html"
18 And I should see "_layouts/simple.html" in the build output
619
720 Scenario: When receiving bad Liquid
821 Given I have a "index.html" page with layout "simple" that contains "{% include invalid.html %}"
5656 And I should see "From your site." in "_site/assets/application.coffee"
5757 And I should see "From your site." in "_site/assets/base.js"
5858
59 Scenario: A theme with *just* layouts
60 Given I have a configuration file with "theme" set to "test-theme-skinny"
61 And I have an "index.html" page with layout "home" that contains "The quick brown fox."
62 When I run jekyll build
63 Then I should get a zero exit status
64 And the _site directory should exist
65 And I should see "Message: The quick brown fox." in "_site/index.html"
66 But I should not see "_includes" in the build output
67 And I should not see "_sass" in the build output
68 And I should not see "assets" in the build output
69
5970 Scenario: Requiring dependencies of a theme
6071 Given I have a configuration file with "theme" set to "test-dependency-theme"
6172 When I run jekyll build
8787 end
8888
8989 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
90 gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
90 # and associated library.
91 install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
92 gem "tzinfo", "~> 1.2"
93 gem "tzinfo-data"
94 end
9195
9296 # Performance-booster for watching directories on Windows
93 gem "wdm", "~> 0.1.0" if Gem.win_platform?
97 gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
9498
9599 RUBY
96100 end
77 mutable false
88
99 def_delegator :@obj, :site_data, :data
10 def_delegators :@obj, :time, :pages, :static_files, :documents,
11 :tags, :categories
10 def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
1211
1312 private def_delegator :@obj, :config, :fallback_data
1413
3837 @site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
3938 end
4039
40 # `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
41 # latest state of the attribute.
42 #
43 # Since this method will be called after `Site#pre_render` hook,
44 # the `Site#documents` array shouldn't thereafter change and can therefore be
45 # safely memoized to prevent additional computation of `Site#documents`.
46 def documents
47 @documents ||= @obj.documents
48 end
49
4150 # `{{ site.related_posts }}` is how posts can get posts related to
4251 # them, either through LSI if it's enabled, or through the most
4352 # recent posts.
3030
3131 def filter(entries)
3232 entries.reject do |e|
33 unless included?(e)
34 special?(e) || backup?(e) || excluded?(e) || symlink?(e)
35 end
33 # Reject this entry if it is a symlink.
34 next true if symlink?(e)
35 # Do not reject this entry if it is included.
36 next false if included?(e)
37 # Reject this entry if it is special, a backup file, or excluded.
38 special?(e) || backup?(e) || excluded?(e)
3639 end
3740 end
3841
127127 #
128128 # Returns excerpt String
129129
130 LIQUID_TAG_REGEX = %r!{%-?\s*(\w+).+\s*-?%}!m
130 LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m
131131 MKDWN_LINK_REF_REGEX = %r!^ {0,3}\[[^\]]+\]:.+$!
132132
133133 def extract_excerpt(doc_content)
134134 head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)
135135
136 # append appropriate closing tag (to a Liquid block), to the "head" if the
137 # partitioning resulted in leaving the closing tag somewhere in the "tail"
138 # partition.
136 # append appropriate closing tag(s) (for each Liquid block), to the `head`
137 # if the partitioning resulted in leaving the closing tag somewhere
138 # in the `tail` partition.
139
139140 if head.include?("{%")
140 head =~ LIQUID_TAG_REGEX
141 tag_name = Regexp.last_match(1)
141 modified = false
142 tag_names = head.scan(LIQUID_TAG_REGEX)
143 tag_names.flatten!
144 tag_names.reverse_each do |tag_name|
145 next unless liquid_block?(tag_name)
146 next if head =~ endtag_regex_stash(tag_name)
142147
143 if liquid_block?(tag_name) && head.match(%r!{%-?\s*end#{tag_name}\s*-?%}!).nil?
144 print_build_warning
148 modified = true
145149 head << "\n{% end#{tag_name} %}"
146150 end
151 print_build_warning if modified
147152 end
148153
149 if tail.empty?
150 head
151 else
152 head.to_s.dup << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
153 end
154 return head if tail.empty?
155
156 head << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
154157 end
155158
156159 private
157160
161 def endtag_regex_stash(tag_name)
162 @endtag_regex_stash ||= {}
163 @endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
164 end
165
158166 def liquid_block?(tag_name)
159 Liquid::Template.tags[tag_name].superclass == Liquid::Block
167 return false unless tag_name.is_a?(String)
168 return false unless Liquid::Template.tags[tag_name]
169
170 Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
160171 rescue NoMethodError
161172 Jekyll.logger.error "Error:",
162173 "A Liquid tag in the excerpt of #{doc.relative_path} couldn't be " \
166177
167178 def print_build_warning
168179 Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
169 Jekyll.logger.warn "",
170 "Found a Liquid block containing separator '#{doc.excerpt_separator}' and has " \
171 "been modified with the appropriate closing tag."
172 Jekyll.logger.warn "",
173 "Feel free to define a custom excerpt or excerpt_separator in the document's " \
174 "Front Matter if the generated excerpt is unsatisfactory."
180 Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
181 " #{doc.excerpt_separator.inspect}. "
182 Jekyll.logger.warn "", "The block has been modified with the appropriate" \
183 " closing tag."
184 Jekyll.logger.warn "", "Feel free to define a custom excerpt or" \
185 " excerpt_separator in the document's front matter" \
186 " if the generated excerpt is unsatisfactory."
175187 end
176188 end
177189 end
5252 private
5353
5454 def filename_regex
55 @filename_regex ||= %r!\A(#{source_dir}/|#{theme_dir}/|\W*)(.*)!i
55 @filename_regex ||= begin
56 %r!\A(#{Regexp.escape(source_dir)}/|#{Regexp.escape(theme_dir.to_s)}/|/*)(.*)!i
57 end
5658 end
5759
5860 def new_profile_hash
313313 #
314314 # Returns an Array of Documents which should be written
315315 def docs_to_write
316 @docs_to_write ||= documents.select(&:write?)
316 documents.select(&:write?)
317317 end
318318
319319 # Get all the documents
320320 #
321321 # Returns an Array of all Documents
322322 def documents
323 collections.reduce(Set.new) do |docs, (_, collection)|
324 docs + collection.docs + collection.files
323 collections.each_with_object(Set.new) do |(_, collection), set|
324 set.merge(collection.docs).merge(collection.files)
325325 end.to_a
326326 end
327327
223223 else
224224 File.join(site.config["collections_dir"], page_payload["path"])
225225 end
226 resource_path.sub!(%r!/#excerpt\z!, "")
226227 site.in_source_dir File.dirname(resource_path)
227228 end
228229 end
5555 end
5656
5757 def realpath_for(folder)
58 File.realpath(Jekyll.sanitized_path(root, folder.to_s))
59 rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
60 Jekyll.logger.warn "Invalid theme folder:", folder
58 # This resolves all symlinks for the theme subfolder and then ensures
59 # that the directory remains inside the theme root. This prevents the
60 # use of symlinks for theme subfolders to escape the theme root.
61 # However, symlinks are allowed to point to other directories within the theme.
62 Jekyll.sanitized_path(root, File.realpath(Jekyll.sanitized_path(root, folder.to_s)))
63 rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP => e
64 log_realpath_exception(e, folder)
6165 nil
66 end
67
68 def log_realpath_exception(err, folder)
69 return if err.is_a?(Errno::ENOENT)
70
71 case err
72 when Errno::EACCES
73 Jekyll.logger.error "Theme error:", "Directory '#{folder}' is not accessible."
74 when Errno::ELOOP
75 Jekyll.logger.error "Theme error:",
76 "Directory '#{folder}' includes a symbolic link loop."
77 end
6278 end
6379
6480 def gemspec
00 # frozen_string_literal: true
11
22 module Jekyll
3 VERSION = "3.8.3".freeze
3 VERSION = "3.8.6".freeze
44 end
0 <!DOCTYPE html>
1 <html>
2 <head>
3 <meta charset="UTF-8">
4 <title>Skinny</title>
5 </head>
6 <body>
7 <h1>Hello World</h1>
8 {{ content }}
9 </body>
10 </html>
0 ---
1 layout: default
2 ---
3
4 Message: {{ content }}
0 # frozen_string_literal: true
1
2 Gem::Specification.new do |s|
3 s.name = "test-theme-skinny"
4 s.version = "0.1.0"
5 s.licenses = ["MIT"]
6 s.summary = "This is a theme with just layouts used to test Jekyll"
7 s.authors = ["Jekyll"]
8 s.files = ["lib/example.rb"]
9 s.homepage = "https://github.com/jekyll/jekyll"
10 end
0 # frozen_string_literal: true
1
2 Gem::Specification.new do |s|
3 s.name = "test-theme-symlink"
4 s.version = "0.1.0"
5 s.licenses = ["MIT"]
6 s.summary = "This is a theme with a symlink used to test Jekyll"
7 s.authors = ["Jekyll"]
8 s.files = ["lib/example.rb"]
9 s.homepage = "https://github.com/jekyll/jekyll"
10 end
194194 skip msg.to_s.magenta
195195 end
196196 end
197
198 def symlink_if_allowed(target, sym_file)
199 FileUtils.ln_sf(target, sym_file)
200 rescue Errno::EACCES
201 skip "Permission denied for creating a symlink to #{target.inspect} " \
202 "on this machine".magenta
203 rescue NotImplementedError => error
204 skip error.to_s.magenta
205 end
197206 end
198207
199208 class FakeLogger
0 # frozen_string_literal: true
1
2 # For testing excerpt handling of custom tags
3
4 module Jekyll
5 class DoNothingBlock < Liquid::Block
6 end
7
8 class DoNothingOther < Liquid::Tag
9 end
10 end
11
12 Liquid::Template.register_tag("do_nothing", Jekyll::DoNothingBlock)
13 Liquid::Template.register_tag("do_nothing_other", Jekyll::DoNothingOther)
11 layout: post
22 ---
33
4 {% if
5 page.layout == "post" %}
6 You’ll find this post in your `_posts` directory.
7 To add new posts, simply add a file in the `_posts` directory.
8 {% endif %}
4 {%
5 highlight
6 ruby
7 %}
8 {% assign foo = 'foobar' %}
9 {% raw
10 %}
11 def print_hi(name)
12 puts "Hi, #{name}"
13 end
14 print_hi('Tom')
15 #=> prints 'Hi, Tom' to STDOUT.
16 {%
17 endraw
18 %}
19 {%
20 endhighlight
21 %}
922
1023 So let's talk business.
11 layout: post
22 ---
33
4 {% if page.layout == "post" %}
5 You’ll find this post in your `_posts` directory.
4 {%
5 highlight
6 ruby
7 %}
8 {% assign foo = 'foobar' %}
9 {% raw
10 %}
11 def print_hi(name)
12 puts "Hi, #{name}"
13 end
614
7 {% else %}
15 print_hi('Tom')
16 #=> prints 'Hi, Tom' to STDOUT.
17 {% endraw %}
18 {% endhighlight %}
819
9 To add new posts, simply add a file in the `_posts` directory.
10 {% endif %}
20 So let's talk business.
0 ---
1 title: liquid_block excerpt test with open tags in excerpt
2 layout: post
3 ---
4
5 {% assign company = "Yoyodyne" %}
6 {% do_nothing_other %}
7 {% do_nothing %}
8 {% unless false %}
9 {% for i in (1..10) %}
10 {% if true %}
11 {% raw %}
12 EVIL! PURE AND SIMPLE FROM THE EIGHTH DIMENSION!
13 {% endraw %}
14 {% elsif false %}
15 No matter where you go, there you are.
16 {% break %}
17 {% else %}
18 {% case company %}
19 {% when "Yoyodyne" %}
20 Buckaroo Banzai
21 {% else %}
22 {% continue %}
23
24 {% endcase %}
25 {% endif %}
26 {% endfor %}
27 {% endunless %}
28 {% enddo_nothing %}
44 class TestEntryFilter < JekyllUnitTest
55 context "Filtering entries" do
66 setup do
7 @site = Site.new(site_configuration)
7 @site = fixture_site
88 end
99
1010 should "filter entries" do
8686 # no support for symlinks on Windows
8787 skip_if_windows "Jekyll does not currently support symlinks on Windows."
8888
89 site = Site.new(site_configuration("safe" => true))
89 site = fixture_site("safe" => true)
9090 site.reader.read_directories("symlink-test")
9191
9292 assert_equal %w(main.scss symlinked-file).length, site.pages.length
9898 # no support for symlinks on Windows
9999 skip_if_windows "Jekyll does not currently support symlinks on Windows."
100100
101 site = Site.new(site_configuration)
101 @site.reader.read_directories("symlink-test")
102 refute_equal [], @site.pages
103 refute_equal [], @site.static_files
104 end
102105
106 should "include only safe symlinks in safe mode even when included" do
107 # no support for symlinks on Windows
108 skip_if_windows "Jekyll does not currently support symlinks on Windows."
109
110 site = fixture_site("safe" => true, "include" => ["symlinked-file-outside-source"])
103111 site.reader.read_directories("symlink-test")
104 refute_equal [], site.pages
105 refute_equal [], site.static_files
112
113 # rubocop:disable Performance/FixedSize
114 assert_equal %w(main.scss symlinked-file).length, site.pages.length
115 refute_includes site.static_files.map(&:name), "symlinked-file-outside-source"
116 # rubocop:enable Performance/FixedSize
106117 end
107118 end
108119
184184 @post = setup_post("2018-01-28-open-liquid-block-excerpt.markdown")
185185 @excerpt = @post.data["excerpt"]
186186
187 assert_includes @post.content, "{% if"
188 refute_includes @post.content.split("\n\n")[0], "{% endif %}"
187 head = @post.content.split("\n\n")[0]
188
189 assert_includes @post.content, "{%\n highlight\n"
190 assert_includes @post.content, "{% raw"
191 refute_includes head, "{% endraw %}"
192 refute_includes head, "{% endhighlight %}"
189193 end
190194
191195 should "be appended to as necessary and generated" do
192 assert_includes @excerpt.content, "{% endif %}"
196 assert_includes @excerpt.content, "{% endraw %}"
197 assert_includes @excerpt.content, "{% endhighlight %}"
193198 assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
194199 end
195200 end
201206 @post = setup_post("2018-01-28-closed-liquid-block-excerpt.markdown")
202207 @excerpt = @post.data["excerpt"]
203208
204 assert_includes @post.content, "{% if"
205 assert_includes @post.content.split("\n\n")[0], "{% endif %}"
209 head = @post.content.split("\n\n")[0]
210
211 assert_includes @post.content, "{%\n highlight\n"
212 assert_includes @post.content, "{% raw"
213 assert_includes head, "{%\n endraw\n%}"
214 assert_includes head, "{%\n endhighlight\n%}"
206215 end
207216
208217 should "not be appended to but generated as is" do
209 assert_includes @excerpt.content, "{% endif %}"
210 refute_includes @excerpt.content, "{% endif %}\n\n{% endif %}"
218 assert_includes @excerpt.content, "{%\n endraw\n%}"
219 assert_includes @excerpt.content, "{%\n endhighlight\n%}"
220 refute_includes @excerpt.content, "{%\n endraw\n%}\n\n{% endraw %}"
221 refute_includes @excerpt.content, "{%\n endhighlight\n%}\n\n{% endhighlight %}"
211222 assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
212223 end
213224 end
263274 assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
264275 end
265276 end
277
278 context "An excerpt with Liquid tags" do
279 setup do
280 clear_dest
281 @site = fixture_site
282 @post = setup_post("2018-11-15-excerpt-liquid-block.md")
283 @excerpt = @post.data["excerpt"]
284
285 assert_includes @post.content.split("\n\n")[0].strip, "{% continue %}"
286 assert_equal true, Jekyll::DoNothingBlock.ancestors.include?(Liquid::Block)
287 assert_equal false, Jekyll::DoNothingOther.ancestors.include?(Liquid::Block)
288 assert_match "Jekyll::DoNothingBlock", Liquid::Template.tags["do_nothing"].name
289 assert_match "Jekyll::DoNothingOther", Liquid::Template.tags["do_nothing_other"].name
290 end
291
292 should "close open block tags, including custom tags, and ignore others" do
293 assert_includes @excerpt.content, "{% endcase %}"
294 assert_includes @excerpt.content, "{% endif %}"
295 assert_includes @excerpt.content, "{% endfor %}"
296 assert_includes @excerpt.content, "{% endunless %}"
297 assert_includes @excerpt.content, "{% enddo_nothing %}"
298 refute_includes @excerpt.content, "{% enddo_nothing_other %}"
299 assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
300 end
301 end
266302 end
1515 end
1616
1717 should "ensure post count is as expected" do
18 assert_equal 57, @site.posts.size
18 assert_equal 58, @site.posts.size
1919 end
2020
2121 should "insert site.posts into the index" do
3030 assert_equal LayoutReader.new(@site).layout_directory, source_dir("blah/_layouts")
3131 end
3232 end
33
34 context "when a layout is a symlink" do
35 setup do
36 symlink_if_allowed("/etc/passwd", source_dir("_layouts", "symlink.html"))
37
38 @site = fixture_site(
39 "safe" => true,
40 "include" => ["symlink.html"]
41 )
42 end
43
44 teardown do
45 FileUtils.rm_f(source_dir("_layouts", "symlink.html"))
46 end
47
48 should "only read the layouts which are in the site" do
49 skip_if_windows "Jekyll does not currently support symlinks on Windows."
50
51 layouts = LayoutReader.new(@site).read
52
53 refute layouts.key?("symlink"), "Should not read the symlinked layout"
54 end
55 end
56
57 context "with a theme" do
58 setup do
59 symlink_if_allowed("/etc/passwd", theme_dir("_layouts", "theme-symlink.html"))
60 @site = fixture_site(
61 "include" => ["theme-symlink.html"],
62 "theme" => "test-theme",
63 "safe" => true
64 )
65 end
66
67 teardown do
68 FileUtils.rm_f(theme_dir("_layouts", "theme-symlink.html"))
69 end
70
71 should "not read a symlink'd theme" do
72 skip_if_windows "Jekyll does not currently support symlinks on Windows."
73
74 layouts = LayoutReader.new(@site).read
75
76 refute layouts.key?("theme-symlink"), \
77 "Should not read symlinked layout from theme"
78 end
79 end
3380 end
3481 end
328328 %(<table class="rouge-table"><tbody>) +
329329 %(<tr><td class="gutter gl">) +
330330 %(<pre class="lineno">1\n</pre></td>) +
331 %(<td class="code"><pre>test</pre></td></tr>) +
331 %(<td class="code"><pre>test\n</pre></td></tr>) +
332332 %(</tbody></table>),
333333 @result
334334 )
475475 expected = <<-EOS
476476 <p>This is not yet highlighted</p>\n
477477 <figure class="highlight"><pre><code class="language-php" data-lang="php"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
478 </pre></td><td class="code"><pre><span class="nx">test</span></pre></td></tr></tbody></table></code></pre></figure>\n
478 </pre></td><td class="code"><pre><span class="nx">test</span>\n</pre></td></tr></tbody></table></code></pre></figure>\n
479479 <p>This should not be highlighted, right?</p>
480480 EOS
481481 assert_match(expected, @result)
7474 refute_file_with_relative_path site.pages, "assets/style.scss"
7575 end
7676 end
77
78 context "symlinked theme" do
79 should "not read assets from symlinked theme" do
80 skip_if_windows "Jekyll does not currently support symlinks on Windows."
81
82 begin
83 tmp_dir = Dir.mktmpdir("jekyll-theme-test")
84 File.open(File.join(tmp_dir, "test.txt"), "wb") { |f| f.write "content" }
85
86 theme_dir = File.join(__dir__, "fixtures", "test-theme-symlink")
87 File.symlink(tmp_dir, File.join(theme_dir, "assets"))
88
89 site = fixture_site(
90 "theme" => "test-theme-symlink",
91 "theme-color" => "black"
92 )
93 ThemeAssetsReader.new(site).read
94
95 assert_empty site.static_files, "static file should not have been picked up"
96 ensure
97 FileUtils.rm_rf(tmp_dir)
98 FileUtils.rm_rf(File.join(theme_dir, "assets"))
99 end
100 end
101 end
77102 end