summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2019-03-15 11:34:26 +0000
committerGitLab Release Tools Bot <robert+release-tools@gitlab.com>2019-04-23 10:10:53 +0000
commitb93b23cb403c8dd4b0a9e9ac89110d99e46a3e68 (patch)
treeb7da0b5e11a83ccdc6fcd2a7101956b6b7e200d7
parenteccfd3ea350a6e4cc0e8ddba3211735e2ae159ed (diff)
downloadgitlab-ce-11-8-stable-patch-8.tar.gz
Merge branch 'sh-handle-null-bytes-in-merge-request-diffs' into 'master'11-8-stable-patch-8
Fix error creating a merge request when diff includes a null byte Closes #57710 See merge request gitlab-org/gitlab-ce!26190 (cherry picked from commit a885e2d0a63b25411995fce2057067348f1bad9b) 6552197e Fix error creating a merge request when diff includes a null byte
-rw-r--r--app/models/merge_request_diff.rb7
-rw-r--r--changelogs/unreleased/sh-handle-null-bytes-in-merge-request-diffs.yml5
-rw-r--r--spec/models/merge_request_diff_spec.rb21
-rw-r--r--spec/support/helpers/repo_helpers.rb14
4 files changed, 46 insertions, 1 deletions
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 481be2da8ac..be2f1319fd2 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -301,6 +301,11 @@ class MergeRequestDiff < ActiveRecord::Base
private
+ def encode_in_base64?(diff_text)
+ (diff_text.encoding == Encoding::BINARY && !diff_text.ascii_only?) ||
+ diff_text.include?("\0")
+ end
+
def create_merge_request_diff_files(diffs)
rows =
if has_attribute?(:external_diff) && Gitlab.config.external_diffs.enabled
@@ -353,7 +358,7 @@ class MergeRequestDiff < ActiveRecord::Base
diff_hash.tap do |hash|
diff_text = hash[:diff]
- if diff_text.encoding == Encoding::BINARY && !diff_text.ascii_only?
+ if encode_in_base64?(diff_text)
hash[:binary] = true
hash[:diff] = [diff_text].pack('m0')
end
diff --git a/changelogs/unreleased/sh-handle-null-bytes-in-merge-request-diffs.yml b/changelogs/unreleased/sh-handle-null-bytes-in-merge-request-diffs.yml
new file mode 100644
index 00000000000..01b6b08b61b
--- /dev/null
+++ b/changelogs/unreleased/sh-handle-null-bytes-in-merge-request-diffs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix error creating a merge request when diff includes a null byte
+merge_request: 26190
+author:
+type: fixed
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index e530e0302f5..53f5307ea0b 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe MergeRequestDiff do
+ include RepoHelpers
+
let(:diff_with_commits) { create(:merge_request).merge_request_diff }
describe 'validations' do
@@ -194,6 +196,25 @@ describe MergeRequestDiff do
expect(diff_file).to be_binary
expect(diff_file.diff).to eq(mr_diff.compare.diffs(paths: [path]).to_a.first.diff)
end
+
+ context 'with diffs that contain a null byte' do
+ let(:filename) { 'test-null.txt' }
+ let(:content) { "a" * 10000 + "\x00" }
+ let(:project) { create(:project, :repository) }
+ let(:branch) { 'null-data' }
+ let(:target_branch) { 'master' }
+
+ it 'saves diffs correctly' do
+ create_file_in_repo(project, target_branch, branch, filename, content)
+
+ mr_diff = create(:merge_request, target_project: project, source_project: project, source_branch: branch, target_branch: target_branch).merge_request_diff
+ diff_file = mr_diff.merge_request_diff_files.find_by(new_path: filename)
+
+ expect(diff_file).to be_binary
+ expect(diff_file.diff).to eq(mr_diff.compare.diffs(paths: [filename]).to_a.first.diff)
+ expect(diff_file.diff).to include(content)
+ end
+ end
end
end
diff --git a/spec/support/helpers/repo_helpers.rb b/spec/support/helpers/repo_helpers.rb
index 3c6956cf5e0..4af90f4af79 100644
--- a/spec/support/helpers/repo_helpers.rb
+++ b/spec/support/helpers/repo_helpers.rb
@@ -115,4 +115,18 @@ eos
commits: commits
)
end
+
+ def create_file_in_repo(
+ project, start_branch, branch_name, filename, content,
+ commit_message: 'Add new content')
+ Files::CreateService.new(
+ project,
+ project.owner,
+ commit_message: commit_message,
+ start_branch: start_branch,
+ branch_name: branch_name,
+ file_path: filename,
+ file_content: content
+ ).execute
+ end
end