Skip to content

Commit

Permalink
Do not traverse symlinks in heuristics (#3946)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashe Connor authored Dec 12, 2017
1 parent 0b81b21 commit d4c2d83
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/linguist/blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ class Blob
#
# path - A path String (does not necessarily exists on the file system).
# content - Content of the file.
# symlink - Whether the file is a symlink.
#
# Returns a Blob.
def initialize(path, content)
def initialize(path, content, symlink: false)
@path = path
@content = content
@symlink = symlink
end

# Public: Filename
Expand Down Expand Up @@ -69,5 +71,12 @@ def extensions
"." + segments[index..-1].join(".")
end
end

# Public: Is this a symlink?
#
# Returns true or false.
def symlink?
@symlink
end
end
end
2 changes: 2 additions & 0 deletions lib/linguist/classifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Classifier
#
# Returns an Array of Language objects, most probable first.
def self.call(blob, possible_languages)
return [] if blob.symlink?

language_names = possible_languages.map(&:name)
classify(Samples.cache, blob.data[0...CLASSIFIER_CONSIDER_BYTES], language_names).map do |name, _|
Language[name] # Return the actual Language objects
Expand Down
5 changes: 5 additions & 0 deletions lib/linguist/file_blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def mode
@mode ||= File.stat(@fullpath).mode.to_s(8)
end

def symlink?
return @symlink if !@symlink.nil?
@symlink = (File.symlink?(@fullpath) rescue false)
end

# Public: Read file contents.
#
# Returns a String.
Expand Down
2 changes: 2 additions & 0 deletions lib/linguist/heuristics.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class Heuristics
#
# Returns an Array of languages, or empty if none matched or were inconclusive.
def self.call(blob, candidates)
return [] if blob.symlink?

data = blob.data[0...HEURISTICS_CONSIDER_BYTES]

@heuristics.each do |heuristic|
Expand Down
5 changes: 5 additions & 0 deletions lib/linguist/lazy_blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ def size
@size
end

def symlink?
# We don't create LazyBlobs for symlinks.
false
end

def cleanup!
@data.clear if @data
end
Expand Down
2 changes: 2 additions & 0 deletions lib/linguist/shebang.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Shebang
# Returns an Array with one Language if the blob has a shebang with a valid
# interpreter, or empty if there is no shebang.
def self.call(blob, _ = nil)
return [] if blob.symlink?

Language.find_by_interpreter interpreter(blob.data)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/linguist/strategy/modeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class Modeline
# Returns an Array with one Language if the blob has a Vim or Emacs modeline
# that matches a Language name or alias. Returns an empty array if no match.
def self.call(blob, _ = nil)
return [] if blob.symlink?

header = blob.first_lines(SEARCH_SCOPE).join("\n")
footer = blob.last_lines(SEARCH_SCOPE).join("\n")
Array(Language.find_by_alias(modeline(header + footer)))
Expand Down

0 comments on commit d4c2d83

Please sign in to comment.