Limit the size of SVGs when viewing them as blobs
This ensures that SVGs greater than 2 megabytes are not scrubbed and rendered. This in turn prevents requests from timing out due to reading/scrubbing large SVGs potentially taking a lot of time (and memory). The use of 2 megabytes is completely arbitrary. Fixes gitlab-org/gitlab-ce#1435
This commit is contained in:
parent
30f5b9a5b7
commit
8171544b3d
4 changed files with 41 additions and 5 deletions
|
@ -32,6 +32,7 @@ v 8.11.0 (unreleased)
|
||||||
- Add "No one can push" as an option for protected branches. !5081
|
- Add "No one can push" as an option for protected branches. !5081
|
||||||
- Improve performance of AutolinkFilter#text_parse by using XPath
|
- Improve performance of AutolinkFilter#text_parse by using XPath
|
||||||
- Add experimental Redis Sentinel support !1877
|
- Add experimental Redis Sentinel support !1877
|
||||||
|
- Rendering of SVGs as blobs is now limited to SVGs with a size smaller or equal to 2MB
|
||||||
- Fix branches page dropdown sort initial state (ClemMakesApps)
|
- Fix branches page dropdown sort initial state (ClemMakesApps)
|
||||||
- Environments have an url to link to
|
- Environments have an url to link to
|
||||||
- Various redundant database indexes have been removed
|
- Various redundant database indexes have been removed
|
||||||
|
|
|
@ -3,6 +3,9 @@ class Blob < SimpleDelegator
|
||||||
CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute
|
CACHE_TIME = 60 # Cache raw blobs referred to by a (mutable) ref for 1 minute
|
||||||
CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour
|
CACHE_TIME_IMMUTABLE = 3600 # Cache blobs referred to by an immutable reference for 1 hour
|
||||||
|
|
||||||
|
# The maximum size of an SVG that can be displayed.
|
||||||
|
MAXIMUM_SVG_SIZE = 2.megabytes
|
||||||
|
|
||||||
# Wrap a Gitlab::Git::Blob object, or return nil when given nil
|
# Wrap a Gitlab::Git::Blob object, or return nil when given nil
|
||||||
#
|
#
|
||||||
# This method prevents the decorated object from evaluating to "truthy" when
|
# This method prevents the decorated object from evaluating to "truthy" when
|
||||||
|
@ -31,6 +34,10 @@ class Blob < SimpleDelegator
|
||||||
text? && language && language.name == 'SVG'
|
text? && language && language.name == 'SVG'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def size_within_svg_limits?
|
||||||
|
size <= MAXIMUM_SVG_SIZE
|
||||||
|
end
|
||||||
|
|
||||||
def video?
|
def video?
|
||||||
UploaderHelper::VIDEO_EXT.include?(extname.downcase.delete('.'))
|
UploaderHelper::VIDEO_EXT.include?(extname.downcase.delete('.'))
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
.file-content.image_file
|
.file-content.image_file
|
||||||
- if blob.svg?
|
- if blob.svg?
|
||||||
|
- if blob.size_within_svg_limits?
|
||||||
- # We need to scrub SVG but we cannot do so in the RawController: it would
|
- # We need to scrub SVG but we cannot do so in the RawController: it would
|
||||||
- # be wrong/strange if RawController modified the data.
|
- # be wrong/strange if RawController modified the data.
|
||||||
- blob.load_all_data!(@repository)
|
- blob.load_all_data!(@repository)
|
||||||
- blob = sanitize_svg(blob)
|
- blob = sanitize_svg(blob)
|
||||||
%img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"}
|
%img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"}
|
||||||
|
- else
|
||||||
|
.nothing-here-block
|
||||||
|
The SVG could not be displayed as it is too large, you can
|
||||||
|
#{link_to('view the raw file', namespace_project_raw_path(@project.namespace, @project, @id), target: '_blank')}
|
||||||
|
instead.
|
||||||
- else
|
- else
|
||||||
%img{src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path))}
|
%img{src: namespace_project_raw_path(@project.namespace, @project, tree_join(@commit.id, blob.path))}
|
||||||
|
|
|
@ -94,4 +94,26 @@ describe Blob do
|
||||||
expect(blob.to_partial_path).to eq 'download'
|
expect(blob.to_partial_path).to eq 'download'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#size_within_svg_limits?' do
|
||||||
|
let(:blob) { described_class.decorate(double(:blob)) }
|
||||||
|
|
||||||
|
it 'returns true when the blob size is smaller than the SVG limit' do
|
||||||
|
expect(blob).to receive(:size).and_return(42)
|
||||||
|
|
||||||
|
expect(blob.size_within_svg_limits?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns true when the blob size is equal to the SVG limit' do
|
||||||
|
expect(blob).to receive(:size).and_return(Blob::MAXIMUM_SVG_SIZE)
|
||||||
|
|
||||||
|
expect(blob.size_within_svg_limits?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns false when the blob size is larger than the SVG limit' do
|
||||||
|
expect(blob).to receive(:size).and_return(1.terabyte)
|
||||||
|
|
||||||
|
expect(blob.size_within_svg_limits?).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue