Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/ex_doc/formatter/epub/templates.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ defmodule ExDoc.Formatter.EPUB.Templates do
alias ExDoc.Formatter.HTML.Templates, as: H
alias ExDoc.Formatter.EPUB.Assets

defp enc(binary), do: h(URI.encode(binary))

# The actual rendering happens here
defp render_doc(ast), do: ast && ExDoc.DocAST.to_html(ast)

Expand Down
8 changes: 4 additions & 4 deletions lib/ex_doc/formatter/epub/templates/content_template.eex
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
<item id="nav" href="nav.xhtml" media-type="application/xhtml+xml" properties="nav scripted"/>
<item id="cover" href="title.xhtml" media-type="application/xhtml+xml" properties="scripted"/>
<%= for extra <- extras do %>
<item id="<%= URI.encode extra.id %>" href="<%= URI.encode extra.id %>.xhtml" media-type="application/xhtml+xml" properties="scripted"/>
<item id="<%= enc extra.id %>" href="<%= enc extra.id %>.xhtml" media-type="application/xhtml+xml" properties="scripted"/>
<% end %>
<%= for node <- modules ++ tasks do %>
<item id="<%= URI.encode node.id %>" href="<%= URI.encode node.id %>.xhtml" media-type="application/xhtml+xml" properties="scripted"/>
<item id="<%= enc node.id %>" href="<%= enc node.id %>.xhtml" media-type="application/xhtml+xml" properties="scripted"/>
<% end %>
<%= for {static_file, media_type} <- static_files do %>
<item id="<%= static_file_to_id(static_file) %>" href="<%= static_file %>" media-type="<%= media_type %>"/>
Expand All @@ -37,10 +37,10 @@
<itemref idref="cover"/>
<itemref idref="nav"/>
<%= for extra <- extras do %>
<itemref idref="<%= URI.encode extra.id %>"/>
<itemref idref="<%= enc extra.id %>"/>
<% end %>
<%= for node <- modules ++ tasks do %>
<itemref idref="<%= URI.encode node.id %>"/>
<itemref idref="<%= enc node.id %>"/>
<% end %>
</spine>
</package>
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ol>
<% end %>
<%= for node <- nodes do %>
<li><a href="<%= URI.encode node.id %>.xhtml"><%=h node.title %></a></li>
<li><a href="<%= enc node.id %>.xhtml"><%=h node.title %></a></li>
<% end %>
<%= if title do %>
</ol>
Expand Down
22 changes: 22 additions & 0 deletions test/ex_doc/formatter/epub_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,28 @@ defmodule ExDoc.Formatter.EPUBTest do
assert content =~ ~r{<dc:creator id="author2">Jane Doe</dc:creator>}
end

test "escapes ids and hrefs built from a configured filename", %{tmp_dir: tmp_dir} = context do
extra = tmp_dir <> "/readme.md"
File.write!(extra, "# Hello\n")

generate_and_unzip(context, config(context, extras: [{extra, filename: "a&b"}]))

content = File.read!(tmp_dir <> "/epub/OEBPS/content.opf")
assert content =~ ~s{<item id="a&amp;b" href="a&amp;b.xhtml"}
assert content =~ ~s{<itemref idref="a&amp;b"/>}

nav = File.read!(tmp_dir <> "/epub/OEBPS/nav.xhtml")
assert nav =~ ~s{<a href="a&amp;b.xhtml">}

# an unescaped & here is a fatal XML error, not a quirk
for file <- ["content.opf", "nav.xhtml"] do
(tmp_dir <> "/epub/OEBPS/" <> file)
|> File.read!()
|> :binary.bin_to_list()
|> :xmerl_scan.string()
end
end

test "generates an EPUB file in the default directory", %{tmp_dir: tmp_dir} = context do
generate(config(context))
assert File.regular?(tmp_dir <> "/epub/#{config(context)[:project]}.epub")
Expand Down
Loading