Skip to content

Commit

Permalink
fixes #5: in case of include recursion the parse will throw an error
Browse files Browse the repository at this point in the history
  • Loading branch information
zookzook committed Dec 19, 2019
1 parent a94203b commit d2700a1
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
3 changes: 1 addition & 2 deletions lib/hocon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ defmodule Hocon do
## Example
iex(1)> conf = ~s(animal { favorite : "dog" }, key : \"\"\"${animal.favorite} is my favorite animal\"\"\")
"animal { favorite : \\"dog\\" }, key : \\"\\"\\"${animal.favorite} is my favorite animal\\"\\"\\""
iex(2)> Hocon.decode(conf)
{:ok,
%{"animal" => %{"favorite" => "dog"}, "key" => "dog is my favorite animal"}}
Expand Down Expand Up @@ -46,7 +45,7 @@ defmodule Hocon do
{ x : 10, y : ${a.x} }
In the case we use the Hocon.FileResolver (which is the default as well):
In the case we use the `Hocon.FileResolver` (which is the default as well):
iex> conf = ~s({ a : { include "./test/data/include-1" } })
iex> Hocon.decode(conf, resolver: Hocon.FileResolver)
Expand Down
19 changes: 16 additions & 3 deletions lib/hocon/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ defmodule Hocon.Parser do
with {[], result } <- ast
|> contact_rule([])
|> parse_root(opts) do
Document.convert(result, opts)
Document.convert(result, Keyword.put(opts, :included_files, []))
end
end
end
Expand Down Expand Up @@ -107,17 +107,30 @@ defmodule Hocon.Parser do
# loads and parse the content of the `file`
##
defp load_configuration_file(file, opts) do
with {:ok, conf} <- load_contents_of_file(file, opts),

included_files = Keyword.get(opts, :included_files, [])

with :ok <- check_recursion(file, included_files),
{:ok, conf} <- load_contents_of_file(file, opts),
{:ok, ast} <- Tokenizer.decode(conf),
{[], result } <- ast
|> contact_rule([])
|> parse_root(opts) do
|> parse_root(Keyword.put(opts, :included_files, [file | included_files])) do
{:ok, result}
else
{:error, reason} -> {:error, reason}
end
end

defp check_recursion(_file, []) do
:ok
end
defp check_recursion(file, included_files) do
case Enum.any?(included_files, fn included_file -> included_file == file end) do
true -> throw {:error, "File " <> file <> " already included."}
false -> :ok
end
end
##
# loads possible extension in combination with the filename
##
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ defmodule Hocon.MixProject do
[main: "Hocon",
name: "HOCON",
extras: ["README.md"],
source_ref: "v#{@version}",
source_ref: "#{@version}",
canonical: "http://hexdocs.pm/hocon",
source_url: "https://github.com/zookzook/hocon"]
end
Expand Down
3 changes: 3 additions & 0 deletions test/data/recursion-1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
b : { include "./test/data/recursion-2.conf" }
}
3 changes: 3 additions & 0 deletions test/data/recursion-2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
c : { include "./test/data/recursion-1.conf" }
}
8 changes: 8 additions & 0 deletions test/parser/include_recursion_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
defmodule Parser.IncludeRecursionTest do
use ExUnit.Case, async: true

test "Tokenize include recursion" do
assert catch_throw(Hocon.decode!(~s({ a : { include "./test/data/recursion-1.conf" } }))) == {:error, "File ./test/data/recursion-1.conf already included."}
end

end

0 comments on commit d2700a1

Please sign in to comment.