Skip to content

Commit 1c0941f

Browse files
authored
Validate extracted escript assets with a hash (#3207)
1 parent 21c1616 commit 1c0941f

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

lib/livebook_cli.ex

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,16 @@ defmodule LivebookCLI do
6161
archive_dir = Path.join(Livebook.Config.tmp_path(), "escript")
6262
extracted_path = Path.join(archive_dir, "extracted")
6363
in_archive_priv_path = ~c"livebook/priv"
64+
priv_dir = Path.join(archive_dir, in_archive_priv_path)
6465

6566
# In dev we want to extract fresh directory on every boot
6667
if Livebook.Config.app_version() =~ "-dev" do
6768
File.rm_rf!(archive_dir)
6869
end
6970

70-
# When temporary directory is cleaned by the OS, the directories
71-
# may be left in place, so we use a regular file (extracted) to
72-
# check if the extracted archive is already available
73-
if not File.exists?(extracted_path) do
71+
# The temporary directory may be partially cleaned by the OS, so we store
72+
# a hash of all paths to check if the extracted archive is still complete
73+
if File.read(extracted_path) != {:ok, priv_hash(priv_dir)} do
7474
{:ok, sections} = :escript.extract(:escript.script_name(), [])
7575
archive = Keyword.fetch!(sections, :archive)
7676

@@ -84,10 +84,17 @@ defmodule LivebookCLI do
8484
raise "Livebook failed to extract archive files, reason: #{inspect(error)}"
8585
end
8686

87-
File.touch!(extracted_path)
87+
File.write!(extracted_path, priv_hash(priv_dir))
8888
end
8989

90-
priv_dir = Path.join(archive_dir, in_archive_priv_path)
9190
Application.put_env(:livebook, :priv_dir, priv_dir, persistent: true)
9291
end
92+
93+
defp priv_hash(priv_dir) do
94+
priv_dir
95+
|> Path.join("**/*")
96+
|> Path.wildcard()
97+
|> Enum.sort()
98+
|> :erlang.md5()
99+
end
93100
end

0 commit comments

Comments
 (0)