diff --git a/lib/ex_doc/formatter/epub/templates.ex b/lib/ex_doc/formatter/epub/templates.ex index 2bea6d45c..f88b990c5 100644 --- a/lib/ex_doc/formatter/epub/templates.ex +++ b/lib/ex_doc/formatter/epub/templates.ex @@ -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) diff --git a/lib/ex_doc/formatter/epub/templates/content_template.eex b/lib/ex_doc/formatter/epub/templates/content_template.eex index eecaf0d42..248839186 100644 --- a/lib/ex_doc/formatter/epub/templates/content_template.eex +++ b/lib/ex_doc/formatter/epub/templates/content_template.eex @@ -18,10 +18,10 @@ <%= for extra <- extras do %> - + <% end %> <%= for node <- modules ++ tasks do %> - + <% end %> <%= for {static_file, media_type} <- static_files do %> @@ -37,10 +37,10 @@ <%= for extra <- extras do %> - + <% end %> <%= for node <- modules ++ tasks do %> - + <% end %> diff --git a/lib/ex_doc/formatter/epub/templates/nav_grouped_item_template.eex b/lib/ex_doc/formatter/epub/templates/nav_grouped_item_template.eex index 67b1d0396..22b87e440 100644 --- a/lib/ex_doc/formatter/epub/templates/nav_grouped_item_template.eex +++ b/lib/ex_doc/formatter/epub/templates/nav_grouped_item_template.eex @@ -4,7 +4,7 @@
    <% end %> <%= for node <- nodes do %> -
  1. <%=h node.title %>
  2. +
  3. <%=h node.title %>
  4. <% end %> <%= if title do %>
diff --git a/test/ex_doc/formatter/epub_test.exs b/test/ex_doc/formatter/epub_test.exs index b63624314..96f501082 100644 --- a/test/ex_doc/formatter/epub_test.exs +++ b/test/ex_doc/formatter/epub_test.exs @@ -66,6 +66,28 @@ defmodule ExDoc.Formatter.EPUBTest do assert content =~ ~r{Jane Doe} 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{} + + nav = File.read!(tmp_dir <> "/epub/OEBPS/nav.xhtml") + assert nav =~ ~s{} + + # 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")