Commit 322c9be8 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'dm-gitmodules-parsing' into 'master'

Make .gitmodules parsing more resilient to syntax errors

Closes #26009

See merge request !11803
parents f06daa26 ea7269e4
---
title: Make .gitmodules parsing more resilient to syntax errors
merge_request:
author:
...@@ -1006,31 +1006,39 @@ module Gitlab ...@@ -1006,31 +1006,39 @@ module Gitlab
# Parses the contents of a .gitmodules file and returns a hash of # Parses the contents of a .gitmodules file and returns a hash of
# submodule information. # submodule information.
def parse_gitmodules(commit, content) def parse_gitmodules(commit, content)
results = {} modules = {}
current = "" name = nil
content.split("\n").each do |txt| content.each_line do |line|
if txt =~ /^\s*\[/ case line.strip
current = txt.match(/(?<=").*(?=")/)[0] when /\A\[submodule "(?<name>[^"]+)"\]\z/ # Submodule header
results[current] = {} name = $~[:name]
else modules[name] = {}
next unless results[current] when /\A(?<key>\w+)\s*=\s*(?<value>.*)\z/ # Key/value pair
match_data = txt.match(/(\w+)\s*=\s*(.*)/) key = $~[:key]
next unless match_data value = $~[:value].chomp
target = match_data[2].chomp
results[current][match_data[1]] = target next unless name && modules[name]
modules[name][key] = value
if match_data[1] == "path" if key == 'path'
begin begin
results[current]["id"] = blob_content(commit, target) modules[name]['id'] = blob_content(commit, value)
rescue InvalidBlobName rescue InvalidBlobName
results.delete(current) # The current entry is invalid
modules.delete(name)
name = nil
end end
end end
when /\A#/ # Comment
next
else # Invalid line
name = nil
end end
end end
results modules
end end
# Returns true if +commit+ introduced changes to +path+, using commit # Returns true if +commit+ introduced changes to +path+, using commit
...@@ -1086,7 +1094,12 @@ module Gitlab ...@@ -1086,7 +1094,12 @@ module Gitlab
elsif tmp_entry.nil? elsif tmp_entry.nil?
return nil return nil
else else
tmp_entry = rugged.lookup(tmp_entry[:oid]) begin
tmp_entry = rugged.lookup(tmp_entry[:oid])
rescue Rugged::OdbError, Rugged::InvalidError, Rugged::ReferenceError
return nil
end
return nil unless tmp_entry.type == :tree return nil unless tmp_entry.type == :tree
tmp_entry = tmp_entry[dir] tmp_entry = tmp_entry[dir]
end end
......
...@@ -381,6 +381,19 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -381,6 +381,19 @@ describe Gitlab::Git::Repository, seed_helper: true do
} }
]) ])
end end
it 'should not break on invalid syntax' do
allow(repository).to receive(:blob_content).and_return(<<-GITMODULES.strip_heredoc)
[submodule "six"]
path = six
url = git://github.com/randx/six.git
[submodule]
foo = bar
GITMODULES
expect(submodules).to have_key('six')
end
end end
context 'where repo doesn\'t have submodules' do context 'where repo doesn\'t have submodules' 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