@@ -77,8 +77,8 @@ create(Metadata, Files, Config) ->
7777 {error , {tarball , {file_too_big , " metadata.config" }}};
7878 true ->
7979 case validate_create_files (Files , FilesRoot ) of
80- ok ->
81- ContentsTarball = create_memory_tarball (Files ),
80+ { ok , ValidatedFiles } ->
81+ ContentsTarball = create_memory_tarball (ValidatedFiles ),
8282 ContentsTarballCompressed = gzip (ContentsTarball ),
8383 InnerChecksum = inner_checksum (? VERSION , MetadataBinary , ContentsTarballCompressed ),
8484 InnerChecksumBase16 = encode_base16 (InnerChecksum ),
@@ -143,8 +143,8 @@ create_docs(Files, Config) ->
143143 FilesRoot = maps :get (tarball_files_root , Config , undefined ),
144144
145145 case validate_create_files (Files , FilesRoot ) of
146- ok ->
147- UncompressedTarball = create_memory_tarball (Files ),
146+ { ok , ValidatedFiles } ->
147+ UncompressedTarball = create_memory_tarball (ValidatedFiles ),
148148
149149 case valid_size (UncompressedTarball , TarballMaxUncompressedSize ) of
150150 true ->
@@ -353,6 +353,8 @@ format_error({tarball, {too_big_compressed, Size}}) ->
353353 io_lib :format (" package exceeds max compressed size ~w ~s " , [format_byte_size (Size ), " MB" ]);
354354format_error ({tarball , {missing_files , Files }}) ->
355355 io_lib :format (" missing files: ~p " , [Files ]);
356+ format_error ({tarball , missing_files_root }) ->
357+ " tarball files root is required when creating tarballs from filesystem paths" ;
356358format_error ({tarball , {bad_version , Vsn }}) ->
357359 io_lib :format (" unsupported version: ~p " , [Vsn ]);
358360format_error ({tarball , invalid_checksum }) ->
@@ -651,17 +653,21 @@ guess_build_tools(Metadata) ->
651653
652654% % @private
653655validate_create_files (Files , FilesRoot ) when is_list (Files ) ->
654- validate_create_files (Files , FilesRoot , ok ).
656+ validate_create_files (Files , FilesRoot , [] ).
655657
656- validate_create_files (_Files , _FilesRoot , {error , _ } = Error ) ->
657- Error ;
658- validate_create_files ([], _FilesRoot , ok ) ->
659- ok ;
660- validate_create_files ([File | Rest ], FilesRoot , ok ) ->
661- validate_create_files (Rest , FilesRoot , validate_create_file (File , FilesRoot )).
658+ validate_create_files ([], _FilesRoot , Acc ) ->
659+ {ok , lists :reverse (Acc )};
660+ validate_create_files ([File | Rest ], FilesRoot , Acc ) ->
661+ case validate_create_file (File , FilesRoot ) of
662+ {ok , ValidatedFile } -> validate_create_files (Rest , FilesRoot , [ValidatedFile | Acc ]);
663+ {error , _ } = Error -> Error
664+ end .
662665
663666validate_create_file ({Filename , Contents }, _FilesRoot ) when is_list (Filename ), is_binary (Contents ) ->
664- validate_archive_path (Filename );
667+ case validate_archive_path (Filename ) of
668+ ok -> {ok , {Filename , Contents }};
669+ {error , _ } = Error -> Error
670+ end ;
665671validate_create_file (Filename , FilesRoot ) when is_list (Filename ) ->
666672 validate_create_file ({Filename , Filename }, FilesRoot );
667673validate_create_file ({Filename , AbsFilename }, FilesRoot ) when is_list (Filename ), is_list (AbsFilename ) ->
@@ -677,26 +683,47 @@ validate_archive_path(Filename) ->
677683 end .
678684
679685validate_source_file (ArchiveName , SourcePath , FilesRoot ) ->
680- case file :read_link_info (SourcePath , []) of
686+ case validate_source_path (SourcePath ) of
687+ ok -> validate_source_file_root (ArchiveName , SourcePath , FilesRoot );
688+ {error , _ } = Error -> Error
689+ end .
690+
691+ validate_source_path (SourcePath ) ->
692+ case safe_relative_archive_path (SourcePath ) of
693+ false -> {error , {tarball , {unsafe_path , SourcePath }}};
694+ true -> ok
695+ end .
696+
697+ validate_source_file_root (_ArchiveName , _SourcePath , undefined ) ->
698+ {error , {tarball , missing_files_root }};
699+ validate_source_file_root (ArchiveName , SourcePath , FilesRoot ) ->
700+ Root = filename :absname (FilesRoot ),
701+ DiskPath = filename :join (Root , SourcePath ),
702+ case file :read_link_info (DiskPath , []) of
681703 {ok , # file_info {type = Type }} when Type =:= regular ; Type =:= directory ->
682- validate_source_root (ArchiveName , SourcePath , FilesRoot );
704+ case validate_source_root (ArchiveName , SourcePath , Root ) of
705+ ok -> {ok , {ArchiveName , DiskPath }};
706+ {error , _ } = Error -> Error
707+ end ;
683708 {ok , # file_info {type = symlink }} ->
684- {ok , LinkTarget } = file :read_link (SourcePath ),
709+ {ok , LinkTarget } = file :read_link (DiskPath ),
685710 ResolvedTarget = archive_join (archive_dirname (ArchiveName ), LinkTarget ),
686711 case safe_relative_archive_path (ResolvedTarget ) of
687712 false -> {error , {tarball , {unsafe_symlink , ArchiveName , LinkTarget }}};
688- true -> ok
713+ true ->
714+ case validate_source_root (ArchiveName , SourcePath , Root ) of
715+ ok -> {ok , {ArchiveName , DiskPath }};
716+ {error , _ } = Error -> Error
717+ end
689718 end ;
690719 {ok , # file_info {type = Type }} ->
691720 {error , {tarball , {unsupported_file_type , ArchiveName , Type }}};
692721 _ ->
693- ok
722+ { ok , { ArchiveName , DiskPath }}
694723 end .
695724
696- validate_source_root (_ArchiveName , _SourcePath , undefined ) ->
697- ok ;
698725validate_source_root (ArchiveName , SourcePath , FilesRoot ) ->
699- case filelib :safe_relative_path (SourcePath , filename : absname ( FilesRoot ) ) of
726+ case filelib :safe_relative_path (SourcePath , FilesRoot ) of
700727 unsafe -> {error , {tarball , {unsafe_path , ArchiveName }}};
701728 _ -> ok
702729 end .
0 commit comments