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
|
||||
- Improve performance of AutolinkFilter#text_parse by using XPath
|
||||
- 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)
|
||||
- Environments have an url to link to
|
||||
- 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_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
|
||||
#
|
||||
# This method prevents the decorated object from evaluating to "truthy" when
|
||||
|
@ -31,6 +34,10 @@ class Blob < SimpleDelegator
|
|||
text? && language && language.name == 'SVG'
|
||||
end
|
||||
|
||||
def size_within_svg_limits?
|
||||
size <= MAXIMUM_SVG_SIZE
|
||||
end
|
||||
|
||||
def video?
|
||||
UploaderHelper::VIDEO_EXT.include?(extname.downcase.delete('.'))
|
||||
end
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
.file-content.image_file
|
||||
- if blob.svg?
|
||||
- # We need to scrub SVG but we cannot do so in the RawController: it would
|
||||
- # be wrong/strange if RawController modified the data.
|
||||
- blob.load_all_data!(@repository)
|
||||
- blob = sanitize_svg(blob)
|
||||
%img{src: "data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"}
|
||||
- if blob.size_within_svg_limits?
|
||||
- # We need to scrub SVG but we cannot do so in the RawController: it would
|
||||
- # be wrong/strange if RawController modified the data.
|
||||
- blob.load_all_data!(@repository)
|
||||
- blob = sanitize_svg(blob)
|
||||
%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
|
||||
%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'
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue