Commit 09a4a5af authored by Grzegorz Bizon's avatar Grzegorz Bizon

Render only valid paths in artifacts metadata

In this version we will support only relative paths in artifacts
metadata. Support for absolute paths will be introduced later.
parent 61fb47a4
...@@ -16,7 +16,10 @@ class Projects::ArtifactsController < Projects::ApplicationController ...@@ -16,7 +16,10 @@ class Projects::ArtifactsController < Projects::ApplicationController
def browse def browse
return render_404 unless build.artifacts? return render_404 unless build.artifacts?
@path = build.artifacts_metadata_path(params[:path].to_s)
directory = params[:path] ? "#{params[:path]}/" : ''
@path = build.artifacts_metadata_path(directory)
return render_404 unless @path.exists? return render_404 unless @path.exists?
end end
......
...@@ -347,10 +347,8 @@ module Ci ...@@ -347,10 +347,8 @@ module Ci
artifacts? && artifacts_file.path.end_with?('zip') && artifacts_metadata.exists? artifacts? && artifacts_file.path.end_with?('zip') && artifacts_metadata.exists?
end end
def artifacts_metadata_path(path) def artifacts_metadata_path(path)
metadata_file = artifacts_metadata.path Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_path
Gitlab::Ci::Build::Artifacts::Metadata.new(metadata_file, path).to_path
end end
private private
......
...@@ -12,7 +12,6 @@ module Gitlab ...@@ -12,7 +12,6 @@ module Gitlab
def initialize(file, path) def initialize(file, path)
@file, @path = file, path @file, @path = file, path
@full_version = read_version @full_version = read_version
@path << '/' unless path.end_with?('/') || path.empty?
end end
def version def version
...@@ -43,14 +42,15 @@ module Gitlab ...@@ -43,14 +42,15 @@ module Gitlab
def match_entries(gz) def match_entries(gz)
paths, metadata = [], [] paths, metadata = [], []
child_pattern = %r{^#{Regexp.escape(@path)}[^/\s]*/?$} match_pattern = %r{^#{Regexp.escape(@path)}[^/\s]*/?$}
until gz.eof? do until gz.eof? do
begin begin
path = read_string(gz) path = read_string(gz)
meta = read_string(gz) meta = read_string(gz)
next unless path =~ child_pattern next unless path =~ match_pattern
next unless path_valid?(path)
paths.push(path) paths.push(path)
metadata.push(JSON.parse(meta.chomp, symbolize_names: true)) metadata.push(JSON.parse(meta.chomp, symbolize_names: true))
...@@ -62,6 +62,10 @@ module Gitlab ...@@ -62,6 +62,10 @@ module Gitlab
[paths, metadata] [paths, metadata]
end end
def path_valid?(path)
!(path.start_with?('/') || path =~ %r{\.?\./})
end
def read_version def read_version
gzip do|gz| gzip do|gz|
version_string = read_string(gz) version_string = read_string(gz)
......
...@@ -23,7 +23,7 @@ module Gitlab ...@@ -23,7 +23,7 @@ module Gitlab
end end
def directory? def directory?
@path.end_with?('/') || @path.blank? blank_node? || @path.end_with?('/')
end end
def file? def file?
...@@ -40,11 +40,11 @@ module Gitlab ...@@ -40,11 +40,11 @@ module Gitlab
end end
def basename def basename
directory? ? name + ::File::SEPARATOR : name (directory? && !blank_node?) ? name + ::File::SEPARATOR : name
end end
def name def name
@name || @path.split(::File::SEPARATOR).last @name || @path.split(::File::SEPARATOR).last.to_s
end end
def children def children
...@@ -83,7 +83,11 @@ module Gitlab ...@@ -83,7 +83,11 @@ module Gitlab
end end
def exists? def exists?
@path.blank? || @universe.include?(@path) blank_node? || @universe.include?(@path)
end
def blank_node?
@path.empty? # "" is considered to be './'
end end
def to_s def to_s
......
...@@ -108,14 +108,14 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do ...@@ -108,14 +108,14 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Path do
end end
end end
describe '#nodes', path: './test' do describe '#nodes', path: 'test' do
subject { |example| path(example).nodes } subject { |example| path(example).nodes }
it { is_expected.to eq 2 } it { is_expected.to eq 1 }
end end
describe '#nodes', path: './test/' do describe '#nodes', path: 'test/' do
subject { |example| path(example).nodes } subject { |example| path(example).nodes }
it { is_expected.to eq 2 } it { is_expected.to eq 1 }
end end
describe '#metadata' do describe '#metadata' do
......
...@@ -28,8 +28,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do ...@@ -28,8 +28,8 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
end end
end end
describe '#match! other_artifacts_0.1.2' do describe '#match! other_artifacts_0.1.2/' do
subject { metadata('other_artifacts_0.1.2').match! } subject { metadata('other_artifacts_0.1.2/').match! }
it 'matches correct paths' do it 'matches correct paths' do
expect(subject.first). expect(subject.first).
...@@ -39,7 +39,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do ...@@ -39,7 +39,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
end end
end end
describe '#match! other_artifacts_0.1.2/another-subdirectory' do describe '#match! other_artifacts_0.1.2/another-subdirectory/' do
subject { metadata('other_artifacts_0.1.2/another-subdirectory/').match! } subject { metadata('other_artifacts_0.1.2/another-subdirectory/').match! }
it 'matches correct paths' do it 'matches correct paths' do
...@@ -52,7 +52,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do ...@@ -52,7 +52,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
describe '#to_path' do describe '#to_path' do
subject { metadata('').to_path } subject { metadata('').to_path }
it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metdata::Path) } it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Path) }
end end
describe '#full_version' do describe '#full_version' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment